якщо, elif, інакше проблеми із заявою в Bash


358

Я не можу зрозуміти, що проблема із наступним ifтвердженням стосується elifта then. Майте на увазі, що printfвсе ще знаходиться в стадії розробки, я просто не зміг перевірити це ще у заяві, тому більш ніж ймовірно помиляється.

Помилка, яку я отримую:

./timezone_string.sh: line 14: syntax error near unexpected token `then'
./timezone_string.sh: line 14: `then'

І заява така.

if [ "$seconds" -eq 0 ];then
   $timezone_string="Z"
elif[ "$seconds" -gt 0 ]
then
   $timezone_string=`printf "%02d:%02d" $seconds/3600 ($seconds/60)%60`
else
   echo "Unknown parameter"
fi

7
Цікаво , чому ми потрібні в thenзаяві , ifі , elifале не в else, а також в цілому.

@ w17t, оскільки нам потрібно відокремити умову від послідовності.
Сашко

3
@codeforester Я не бачу великої логіки, коли маркування 500K розглядає питання як дублікат на те, що має лише 5K
fedorqui 'ТАК перестаньте шкодити'

Використання деяких інструментів автоматичного форматування коду може допомогти вам, автоматично додаючи / видаляючи пробіли навколо дужок. Ви можете шукати плагіни для свого редактора.
Nj

Відповіді:


453

Місця elifта [: немає місця

elif[ "$seconds" -gt 0 ]

має бути

elif [ "$seconds" -gt 0 ]

Як я бачу, це питання набирає багато переглядів, важливо вказати, що синтаксис, який слід дотримуватися, це:

if [ conditions ]
# ^ ^          ^

означає, що навколо дужок потрібні пробіли . Інакше це не спрацює. Це тому, що [сама по собі є командою.

Причина , чому ви не бачите що - щось на зразок elif[: command not found(або аналогічний) , є те , що після перегляду ifі then, оболонка шукає або elif, elseабо fi. Однак він знаходить інше then(після неправильно відформатованого elif[). Тільки після розбору оператора воно буде виконуватися (і буде видано повідомлення про помилку як elif[: command not found).


33
Причиною, що дужкам потрібні пробіли, є те, що вони є лише ярликами для фактичних програм (принаймні, перша дужка, друга - просто синтаксичний цукор, наскільки я це розумію). Щоб зрозуміти це, дивіться фактичну сторінку для лівої дужки:$ man [
Майкл Йохансен

3
Чи не слід цю посаду закривати як друкарську помилку?
zx8754

3
@ zx8754 міг бути, але це не стало канонічним способом виправити цю помилку, яка виглядає досить корисною (360K переглядів та підрахунку).
fedorqui 'ТАК перестаньте шкодити'

3
Деякі з моїх колег не розуміють поняття "простір" чи "стиль кодування", тому це може бути не помилковою помилкою.
джузлін

3
[є своєрідним псевдонімом для тестової команди. Ось чому потрібен порожній символ. if test "$seconds" -eq 0; then ... fiеквівалентно if [ "$seconds" -eq 0 ];then ... fi ]. @LeiYang man testє те , що ви на насправді шукає
Melicerte

303

У вас є деякі проблеми з синтаксисом зі своїм сценарієм. Ось фіксована версія:

#!/bin/bash

if [ "$seconds" -eq 0 ]; then
   timezone_string="Z"
elif [ "$seconds" -gt 0 ]; then
   timezone_string=$(printf "%02d:%02d" $((seconds/3600)) $(((seconds / 60) % 60)))
else
   echo "Unknown parameter"
fi

76
Як не дивно, це була єдина повноцінна і проста bash конструкція "якщо тоді ще", яку я легко знайшов на stackexchange ... дякую.
Wildcard

1
відступ необов’язковий. перекладач може (і повинен) бути #!/bin/sh.

3
@ Chinggis6 Загальна дурниця, перекладач може бути, #!/bin/shале не повинен.
Камюнсей

4
@Camusensei - це не загальна дурниця, оскільки shзамість неї можна використовувати для вищої сумісності (не всі * nix distros мають bash як оболонку за замовчуванням (деякі мають ksh або ash, але більшість з них залежить від стандарту shдля функціонування). Більше того, якщо баш-специфічний або додаткові функції не використовуються в скрипті, тоді "sh" слід використовувати як інтерпретатор (ще одна причина цього), оскільки він може сам обробляти сценарій.

6
@ Chinggis6 Правда, поганий вибір слів на моєму боці.
Camusensei

25

[це команда (або вбудований в деяких оболонках). Він повинен бути відокремлений пробілом від попереднього твердження:

elif [

3
Його заміняє вбудований в bash, але ваше повідомлення все ще правильне. використовувати, type -a [щоб побачити це.
Камюнсей

Це також двійковий файл, який мені завжди здавався дивним.
mr.zog

4

Я б рекомендував вам ознайомитись з основами кондиціонування в баші.

Символ "[" є командою і повинен мати перед собою пробіл. Якщо ви не надаєте пробіли після вашого elif, система трактує elif [ як конкретну команду, яка точно не є тим, що ви хотіли б у цей час.

Використання:

elif(A COMPULSORY WHITESPACE WITHOUT PARENTHESIS)[(A WHITE SPACE WITHOUT PARENTHESIS)conditions(A WHITESPACE WITHOUT PARENTHESIS)]

Коротше кажучи, відредагуйте сегмент коду таким чином:

elif [ "$seconds" -gt 0 ]

Ви будете добре без помилок компіляції. Ваш остаточний сегмент коду повинен виглядати так:

#!/bin/sh    
if [ "$seconds" -eq 0 ];then
       $timezone_string="Z"
    elif [ "$seconds" -gt 0 ]
    then
       $timezone_string=`printf "%02d:%02d" $seconds/3600 ($seconds/60)%60`
    else
       echo "Unknown parameter"
    fi

2

Не вистачає місця між вашою програмою elifта [спокою. вам потрібно виправити це, перевірити. тут зафіксована програма:

#!/bin/bash

if [ "$seconds" -eq 0 ]; then
   timezone_string="Z"
elif [ "$seconds" -gt 0 ]; then
   timezone_string=$(printf "%02d:%02d" $((seconds/3600)) $(((seconds / 60) % 60)))
else
   echo "Unknown parameter"
fi

корисне посилання, пов'язане з цим bash, якщо інше твердження

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.