Comment puis-je diviser une commande sur plusieurs lignes lors de l'utilisation d'une instruction if?

Comment puis-je diviser une commande sur plusieurs lignes dans le shell, lorsque la commande est partie d'un if déclaration?

Cela fonctionne:

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

Cela ne fonctionne pas:

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

Au lieu de l'exécution de toute la commande, je reçois:

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

Plus important encore, qu'est-ce qui manque à ma compréhension de Bash qui m'aidera à comprendre cela et des problèmes similaires à l'avenir?

264
demandé sur codeforester 2013-09-03 23:10:19

2 réponses

La suite de ligne échouera si vous avez des espaces (espaces ou caractères de tabulation) après la barre oblique inverse et avant le retour à la ligne. Sans un tel espace, Votre exemple fonctionne bien pour moi:

$ 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

Quelques détails promus à partir des commentaires: la barre oblique inverse dans le shell n'est pas un cas particulier; c'est simplement un exemple de la règle générale selon laquelle une barre oblique inverse rend le caractère suivant littéral, empêchant tout effet spécial qu'il pourrait avoir. Dans ce cas, le caractère suivant est un newline, et l'effet spécial empêché termine la ligne de commande. Comme avec toutes les autres échappements antislash, il ne peut y avoir rien entre la barre oblique inverse et le caractère qu'il cite. Si le caractère suivant après la barre oblique inverse est un espace ou un onglet, vous obtenez simplement un espace littéral ou un onglet, et il n'y a aucun effet sur la nouvelle ligne suivante, ce qui termine toujours la commande comme d'habitude.

401
répondu Mark Reed 2018-06-20 13:30:50

Pour les utilisateurs de Windows/Cygwin/WSL etc:

Assurez-vous également que vos fins de ligne sont des flux de ligne Unix standard, c'est-à-dire \n (LF) uniquement. Avoir des terminaisons de ligne Windows \r\n (CRLF) le cassera.

29
répondu Czechnology 2018-08-21 19:35:32