Як я можу розділити команду оболонки на кілька рядків при використанні оператора IF?


384

Як я можу розділити команду на кілька рядків оболонки, коли команда є частиною 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

Що ще важливіше, чого не вистачає в моєму розумінні Баша, що допоможе мені зрозуміти це та подібні проблеми в майбутньому?


2
Що таке помилка? Я можу виконати $ if ! cp -n log/server1.log \ > .; then echo no copy; fiбез помилок з новим рядком після\
Мізерна змінна

15
У вас є пробіли після відкидання терміналу \ ? Їх досить важко помітити. Якщо це зробити, ви можете побачити, чи можете ви зробити редактор або видалити пробіли, або зробити їх більш видимими.
msw

10
Так, це були пробіли після відхилення терміналу. Повністю. Дякую.
Дмитро Міньковський

І так, вибачте, я повинен був розмістити "помилку" (несподіваний результат)! Моє ліжко! Редагування зараз.
Дмитро Мінковський

Що ви розуміли? Це також не є частиною питання.
хакре

Відповіді:


566

Продовження рядка не вдасться, якщо у вас є пробіл (пробіли або символи вкладки) після нахилу та перед новим рядком. Без такого пробілу, ваш приклад для мене працює добре:

$ 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

Деякі деталі, викладені в коментарях: зворотний косий рядок продовження в оболонці насправді не є особливим випадком; це просто примірник загального правила, що зворотна косої риски "цитує" негайно наступного символу, запобігаючи будь-якому спеціальному лікуванню, яке воно, як правило, підлягає. У цьому випадку наступним символом є новий рядок, і спеціальне звернення, яке перешкоджає, - це припинення дії команди. Зазвичай цитований персонаж закінчується буквально включеним в команду; зворотний косий рядок замість цього видаляється повністю. Але в іншому випадку механізм той самий. А зворотна косої риски цитує лише наступного символу; якщо цей символ є пробілом або вкладкою, ви просто отримаєте процитований пробіл або вкладку, і будь-який наступний новий рядок залишається без котирування.


5
Марк, знаєте, у мене, мабуть, були пробіли. Я можу відтворити помилку лише під час додавання пробілів після `s. For example, when adding one after the first `, я отримую ./soundops: line 73: --forward-agent: command not found. Мої проблеми полягали в тому, що я не розумів цієї помилки. Чому наявність пробілу призводить до цієї помилки? Пробіл + \n"заперечує" `` і розмежовує команду?
Дмитро Міньковський

83
Зворотний косий рядок перед новим рядком заважає новому рядку закінчувати команду. Але так само, як спеціальні послідовності евакуації, такі як "\ n", працюють лише з похилою косою рисою та n, ніколи між зворотною косою рисою та новою лінією нічого не працює.
Марк Рід

18
Ха-ха-ха, звичайно, це має сенс. Ніколи так не бачив. Відкриття очей, але настільки просто: це просто вирваний новий рядок. Я ненавиджу невидимих ​​персонажів. Вони мали би для мене набагато більше сенсу, якби вони були просто видимими. Дякую!
Дмитро Міньковський

7
У більшості редакторів можна зробити видимими ці невидимі символи.
lucasvc

1
Зворотний косий рядок та новий рядок видаляються з ефективного командного рядка, але будь-який провідний пробіл у наступному рядку зберігається. Тож чи це проблема чи ні, залежить від того, чи буде пробіл проблемою в цей момент в однорядковій команді.
Марк Рід

52

Для користувачів Windows / WSL / Cygwin тощо:

Переконайтесь, що ваші закінчення рядків є стандартними стрічками рядків Unix, тобто \n(LF).

Використання закінчень рядків Windows \r\n(CRLF) завершить розрив командного рядка.


Це відбувається тому, що наявність \у кінці рядка із закінченням рядка Windows означає переклад \ \r \n.
Як Марк правильно пояснює вище:

Продовження рядка не вдасться, якщо у вас є пробіл після зворотної косої риски та перед новою лінією.

Сюди входить не лише пробіл ( ) або вкладки ( \t), а й повернення каретки ( \r).


1
Це виправляє проблему, створену при створенні скрипту в Windows, а потім його використанні в Windows bash (наприклад, bash -c MyShellScript.sh, де MyShellScript.sh був створений в редакторі Windows). Вам потрібно зберегти MyShellScript.sh у форматі UNIX, можливо, використовуючи блокнот ++.
BSalita
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.