来自 Google 的 Markdown 风格指南:
由于大多数命令行片段旨在直接复制并粘贴到终端中,因此最佳实践是转义任何换行符。在行尾使用单个反斜杠:
bazel run :target -- --flag --foo=longlonglonglonglongvalue \ --bar=anotherlonglonglonglonglonglonglonglonglonglongvalue
有人可以解释一下为什么如果我将以下代码片段复制并粘贴到终端中,转义换行符会导致工作错误(我在 Mac 上使用 zsh,不确定在纯 Bash 和/或其他终端中是否会发生同样的问题。它?):
如果您将此代码段复制并粘贴到终端中,它就可以正常工作:
for (( counter=10; counter>0; counter-- ))
do
echo -n "$counter "
done
printf "\n"
但是如果你复制粘贴这个,就会出现错误:
for (( counter=10; counter>0; counter-- )) \
do \
echo -n "$counter " \
done \
printf "\n"
答案1
换行符 ( NL
, ^J
) 标记行尾,通常结束命令。
转义的 NL 字符被视为空白,并且不会结束命令或行。
foo
bar
是两个命令。
foo \
bar
是一个命令,
foo bar
答案2
\
后面跟着一个换行符是续行,它通常用于将很长的行分成多行以提高可读性。
shell 在读取它们后,只是将它们删除:
ec\
ho t\
est
只是另一种写法:
echo test
和:
for (( counter=10; counter>0; counter-- )) \
do \
echo -n "$counter " \
done \
printf "\n"
还有另一种写法:
for (( counter=10; counter>0; counter-- )) do echo -n "$counter " done printf "\n"
它将在循环中运行echo -n "$counter " done printf "\n"
,除了缺少done
关闭循环的 之外(另一个done
只是 的参数echo
)。
所以你可能想插入一些\<newline>
来打破很长的行,但是你不想要替换<newline>
s (用于分隔命令等),\<newline>
它与以下相同没有什么1.
¹ 除了单引号内(或$'...'
对于那些支持单引号的 shell)或带有引号分隔符的此处文档(如<< "EOF"...EOF
)
答案3
在 shell 语法中,有一个分号 ( ;
) 标记来分隔命令。
作为替代方案,可以使用换行符。换句话说,你可以这样做:
command ; command
或这个:
command
command
shell 中的某些语法结构由多个命令组成,例如循环:
while test-command1; test-comand2 ; do command1; command2; command3; done
从语法上讲,这是六个命令:一个while
标记控制循环的测试命令序列开始的命令。然后是一个do
标记循环体开始的命令。最后一个done
标志着结束的命令。
当写成多行时,分号变为可选:
while test-command-1
test-command-2
do command1
command2
command3
done
现在,反斜杠换行序列(通常称为行延续)将多个物理行转换为单个逻辑行。 Awk 语言、Make 语言和 C 语言的预处理功能中也存在类似的行继续功能。
当我们将 shell 脚本分成多个带有续行的物理行时,解释器只能看到一行。因此,分号是必需的。
错误的:
while test-command-1 \
test-command-2 \
do command1 \
command2 \
command3 \
done
正确的:
while test-command-1 ; \
test-command-2 ; \
do command1 ; \
command2 ; \
command3 ; \
done
在 a 中看到这种情况很常见Makefile
。在 Make 中,构建配方的每一行都是在单独的 shell 实例中运行的单独的 shell 脚本。因此,每个脚本都必须适合 make 语法的单个逻辑行。行延续用于将复杂的 shell 脚本分解为多个物理行,因此需要分号。