якщо, 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.