当使用IF语句时,我如何在多行上分割shell命令?

当命令是if语句的一部分时,如何将命令拆分到shell中的多行?

如此:

if ! fab --fabfile=.deploy/fabfile.py --forward-agent --disable-known-hosts deploy:$target; then rc=1
fi

这行不通:

# does not work:
if ! fab --fabfile=.deploy/fabfile.py \
--forward-agent \
--disable-known-hosts deploy:$target; then
rc=1
fi

而不是整个命令执行,我得到:

./script.sh: line 73: --forward-agent: command not found

更重要的是,我对Bash的理解中缺少了什么,这将帮助我在未来理解这个问题和类似的问题?

534698 次浏览

如果在反斜杠之后和换行符之前有空格(空格或制表符¹),续行将失败。没有这样的空白,你的例子为我工作良好:

$ cat test.sh
if ! fab --fabfile=.deploy/fabfile.py \
--forward-agent \
--disable-known-hosts deploy:$target; then
echo failed
else
echo succeeded
fi


$ alias fab=true; . ./test.sh
succeeded
$ alias fab=false; . ./test.sh
failed

注释中介绍了一些细节:shell中的行延续反斜杠并不是真正的特殊情况;这只是一般规则的一个例子,反斜杠"紧随其后的字符,阻止了它通常会受到的任何特殊处理。在本例中,下一个字符是换行符,被阻止的特殊处理是终止命令。通常,被引用的字符会被逐字地包含在命令中;相反,反切换行符将被完全删除。但除此之外,机理是一样的。最重要的是,反斜杠只引用紧随其后的字符;如果那个字符是一个空格或制表符,你只得到一个文字空格或制表符;反斜杠对后面的换行符没有作用。

¹或回车,就像捷克学指出的那样。POSIX shell不适合windows格式的文本文件,甚至在WSL中也不行。或者Cygwin,但至少他们的Bash端口已经添加了一个igncr选项,你可以set -o使其容忍回车。

对于Windows/WSL/Cygwin等用户:

确保你的行结束符是标准的Unix换行符,即仅\n (LF)。

使用Windows行结束符\r\n (CRLF)行结束符将中断命令行换行符。


这是因为将\放在一行的末尾,并将Windows行的结尾转换为 \ \r \n.
正如Mark在上面正确解释的那样:

如果在反斜杠之后和换行符之前有空格,行延续将失败。

这不仅包括空格符()或制表符(\t),还包括回车符(\r)。