Как я могу разделить команду оболочки на несколько строк при использовании оператора IF?

Как разделить команду на несколько строк в оболочке, если команда является частью оператора if?

Это работает:

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, которое поможет мне понять эту и подобные проблемы в будущем?

Ответ 1

Продолжение строки не будет выполнено, если после обратной косой черты и до новой строки есть пробелы (пробелы или символы табуляции). Без таких пробелов ваш пример отлично работает для меня:

$ 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

Некоторая деталь продвигается из комментариев: обратный слеш продолжения строки в оболочке на самом деле не является особым случаем; это просто пример общего правила, согласно которому обратный слеш предотвращает любую специальную обработку, которой обычно подвергается следующий символ. В этом случае следующий символ - это новая строка, и специальная обработка, которая запрещается, завершает командную строку. (Новая строка действительно отличается от других символов в кавычках тем, что она фактически полностью удаляется из командной строки, а не вставляется буквально.) Поскольку обратная косая черта заключает в себе только кавычки сразу после следующего символа, между обратной косой чертой и символом, который вы используете, не может быть ничего. хочу цитировать; если следующий символ после обратной косой черты является пробелом или символом табуляции, он просто цитирует этот пробел или символ табуляции, что никак не влияет на любой последующий символ новой строки.

Ответ 2

Для пользователей Windows/WSL/Cygwin и т. Д.:

Удостоверьтесь, что ваши окончания строки являются стандартными переводами строки Unix, то есть только \n (LF).

Использование окончаний строки в Windows \r\n (CRLF) означает окончание строки в командной строке.


Это связано с тем, что наличие \ в конце строки с окончанием строки Windows переводится в \ \r \n.
Как правильно объясняет Марк, выше:

Продолжение строки не будет выполнено, если после обратной косой черты и до новой строки появятся пробелы.

Это включает в себя не только пространство () или вкладки (\t), но также возврат каретки (\r).