为什么这个 apt install 命令中有反斜杠 `\` 换行符?

为什么这个 apt install 命令中有反斜杠 `\` 换行符?

当我阅读需要安装许多软件包的教程时,它们通常会\在行尾出现一个反斜杠?

sudo apt install gcc git pkg-config meson ninja-build \
                 libavcodec-dev libavformat-dev libavutil-dev \
                 libsdl2-dev

为什么?当我将命令复制粘贴到 Linux 终端时,它不起作用,我必须删除反斜杠并将所有内容放在一行上。发生了什么?

答案1

bash 使用反斜杠来表示行继续,并且通常用于 bash 脚本。但是,反斜杠实际上bash 转义字符。因此,使用反斜杠“转义”\newline 来创建延续。很酷,而且值得了解,不是吗?特别是,GNU bash 手册第 3.1.2.1 节说:

未加引号的反斜杠 '\' 是 Bash 转义字符。它保留后面的下一个字符的字面值,但换行符除外。如果出现 \newline 对,并且反斜杠本身未加引号,则 \newline 会被视为行延续(即,它会从输入流中删除并被有效忽略)。

回答您的具体问题:作者只是表明多行表达式是单行 bash 命令。如果 '\' 后面没有字符但有 \newline,则此多行表达式将起作用。但是,如果进行剪切和粘贴,'\' 后面可能会有各种杂乱内容(例如空格)。因此,要么删除 '\' 后面的所有尾随字符,要么像您一直做的那样将命令放在一行上。我经常发现在输入长命令时使用 '\' 很方便,但这取决于个人喜好。

答案2

\在 bash 中,行尾的字符被解释为行继续符,它告诉 bash 期望在下一行继续命令,除非:

  • \字符是被单引号或双引号字符括起来的字符串的一部分
  • 或者\通过在字符前面放置另一个反斜杠字符来进行转义,就像这样,\\这使得该字符被解释为文字字符。

笔记:未加引号的反斜杠\在 bash 中也用作转义字符。

将多行命令(如下面的示例)从文本编辑器复制/粘贴到终端会导致该命令作为单行命令执行。

原文:

touch 1 \
2 \
3 \
&& ls

将原文复制/粘贴到终端:

$触摸 1 \
> 2 \
> 3 \
> && ls
1 2 3

当下一个多行命令从文本编辑器复制/粘贴到终端时,将打印反斜杠字符。在此命令中,反斜杠被解释为文字反斜杠字符,因为它们被括在一对(单)引号字符中。

原文:

echo 'This is \
a multiple line \
command.'

在终端中:

$echo'这是\
> 多行 \
> 命令。'
这是 \
多行 \
命令。

此答案中的所有命令最初都是我在文本编辑器中输入的,然后才粘贴到终端中,因此命令中没有不可见的字符,这可能会导致命令不起作用。

答案3

\sh是/中的行继续符,bash就像在 C 语言(用于#定义一个长宏)或其他几种计算机语言中一样,允许在源代码中换行长行,而不会改变面向行的语言中的含义。

只需一次粘贴即可如果所选内容不包含\字符后的任何空格,仅包含换行符。(在 Chromium 中,它显示为一个蓝色字符“框”,看起来像行尾的空格,但显然它实际上是换行符。)一些网页在其格式化代码中包含尾随空格。也许作者从终端复制/粘贴了固定宽度的空格,但没有清理代码块。

您可以通过选择整个内容并查看行尾来直观地判断这一点。 如果代码正确,你可以直接粘贴到终端中。如果代码错误,你可以粘贴到编辑器中并\ ... spaces newline自行折叠。

或者如果不是复杂的话,您可能能够在命令行上粘贴单引号,然后使用向上箭头来修复它。

或者,如果对您来说更方便的话,单独粘贴每一行,省略\...创建一行长代码。或者手动添加\不是在副本中添加尾随空格或换行符,然后在粘贴每一行后按回车键。

如果你无法使用鼠标获得所有想要的字符,Chromium 至少允许你使用 shift+左/右箭头调整选择,但是不是您不想要的字符。


Stack Exchange 代码格式化块可以忠实地再现好的和坏的例子,因此您可以在浏览器中尝试一下,看看要查找什么。

# Good: 
echo 1 \
     2 \
     3 

# Bad: spaces after backslash: needs editing to copy/paste
echo 1 \     
     2 \    
     3 

粘贴结果:\仅转义空格,而不是换行符。每行本身都是无害的,因此可以安全地进行操作。不像rm *应该是其他内容的一部分,或者启动任何实际程序,除非您有别名或 shell 函数调用2或 3`。

peter@volta:/tmp$ echo 1 \     
1  
peter@volta:/tmp$      2 \    
bash: 2: command not found
peter@volta:/tmp$      3 
bash: 3: command not found

无需启动单独的编辑器即可快速修复:

粘贴在单引号内:

$ 'echo 1 \     
>      2 \    
>      3 '
bash: $'echo 1 \\     \n     2 \\    \n     3 ': command not found

请注意,bash 使用$'C-escaped'语法将命令引用给我。我确实按了回车键,将整个命令放入命令行历史记录中。Bash 行编辑不会返回到之前已提交的行,但多行引用的内容会创建一个多行历史记录条目。

从那里向上箭头可以将所有这些作为一条命令,其中包含可编辑的嵌入换行符。您需要删除它们,否则它仍将被解释为多个命令,就像它们是;分号一样。当然也要删除'引号。

Ctrl-w (unix-word-rubout) 将其\视为一个“单词”,并在其后停止。(不同于 Md (escape-d) 删除前一个单词,或 M-backspace(删除后一个单词);这些都会删除单词过去的反斜杠)。Ctrl-w 甚至将换行符视为一个“单词”(这实际上不是我们想要的;从我们想要删除的第一个非空白字符到上一行的\)。

ctrl-left(或 escape-f)/ ctrl-right(或 escape-b)按整个单词移动光标,这样您就可以快速到达 control-w 的“行”的开头。或者 ctrl-r 反向 i 搜索\可以到达那里,然后 ctrl-right + left 到达下一行的第一个单词。

Ctrl-/ 是撤消,这非常方便,因为它可以让您积极地重复按键或其他操作,并快速从过冲中恢复。

如果您经常使用 bash / readline 行编辑,那么您已经记住了许多这些命令。我在这里提到它们只是为了帮助那些对 bash 行编辑经验较少的人,他们可能认为值得将命令复制/粘贴到编辑器中,然后再复制到 bash 中。这当然是一个选择,特别是如果您已经打开了一个编辑器。


另一个可能有用的编辑命令是 M-\(meta/escape 反斜杠)。这会删除光标周围的空格。您只需使用两次,将光标放在后面\,即可将其保留为具有连续性的多行内容\。例如,使用向上箭头调用命令

  • backspace / ctrl-a / delete (或 ctrl-d)删除单引号
  • ctrl-s 向前搜索\,然后按右箭头(或 ctrl-f)将光标移动到\
  • escape- \。 (或者 alt-\如果您的终端已正确设置为 emacs 行编辑 meta-,通常通过发送转义前缀来运行。)
  • ctrl-s ctrl-s 前进 i-再次搜索相同内容
  • 重复右箭头 + 消除空格

我不是建议记忆这些步骤,这只是使用行编辑完成工作的方法之一。

或者您可以删除\和换行符(并将空格折叠为 1 个空格,如果您愿意的话),就像我使用 control-w 建议的那样。当光标位于正确位置时,Delete / ctrl-d 或 backspace 将删除换行符或反斜杠。Bash 行编辑显然没有 emacsM-space将空格折叠为 1 个(而不是 0 个)空格,但您可以使用 M- \+ space 手动执行此操作。

答案4

当您从如下格式的网页复制文本时:

sudo apt install gcc git pkg-config meson ninja-build \
         libavcodec-dev libavformat-dev libavutil-dev \
         libsdl2-dev

并且它不起作用,那么您必须一次复制一行,然后将其一行一行地粘贴到终端中。将每行复制到反斜杠 ( \) 的末尾,并且后面没有空格。

或者,您可以将所有三行复制到gedit另一个编辑器中,删除 \ 并制作如下“单行”代码:

sudo apt install gcc git pkg-config meson ninja-build libavcodec-dev libavformat-dev libavutil-dev libsdl2-dev

然后您可以从编辑器中复制一行并将其粘贴到终端中。

相关内容