当命令是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的理解中缺少了什么,这将帮助我在未来理解这个问题和类似的问题?


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

$ 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

Some detail promoted from the comments: the line-continuation backslash in the shell is not really a special case; it is simply an instance of the general rule that a backslash "quotes" the immediately-following character, preventing any special treatment it would normally be subject to. In this case, the next character is a newline, and the special treatment being prevented is terminating the command. Normally, a quoted character winds up included literally in the command; a backslashed newline is instead deleted entirely. But otherwise, the mechanism is the same. Most importantly, the backslash only quotes the immediately-following character; if that character is a space or tab, you just get a literal space or tab; the backslash will have no effect on a subsequent newline.

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


对于Windows/WSL/Cygwin等用户:

确保你的行结束符是标准的Unix换行符,也就是只使用\n (LF)。

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


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

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

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