当我阅读需要安装许多软件包的教程时,它们通常会\
在行尾出现一个反斜杠?
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
然后您可以从编辑器中复制一行并将其粘贴到终端中。