если, элиф, другие операторы проблемы в Bash

359

Я не могу понять, в чем проблема со следующим 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
StuStirling
источник
7
Интересно , почему мы нужны в thenзаявлении , ifи , elifно не в else, а также в целом.
@ w17t, потому что нам нужно отделить условие от последовательности.
Саша
3
@ codeforester Я не вижу особой логики в том, чтобы пометить вопрос с 500K-просмотрами как дубликат вопроса, который имеет только 5K
fedorqui «ТАК Хватит вредить»
Использование некоторых инструментов автоматического форматирования кода может помочь вам, автоматически добавляя / удаляя пробелы в скобках. Вы можете искать плагины для вашего редактора.
Нью-Джерси Субеди

Ответы:

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 просмотров и подсчет).
Федорки 'ТАК прекрати вредить'
3
Некоторые из моих коллег не понимают понятия «пространство» или «стиль кодирования», поэтому это может быть не опечатка.
Джуззлин
3
[является псевдонимом команды test. Вот почему необходим пустой символ. if test "$seconds" -eq 0; then ... fiэквивалентно if [ "$seconds" -eq 0 ];then ... fi ]. @LeiYang man testявляется то , что вы на самом деле ищет
Melicerte
304

У вас есть некоторые проблемы с синтаксисом в вашем скрипте. Вот исправленная версия:

#!/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но не обязан.
Camusensei
4
@Camusensei это не полная ерунда, так как shее можно использовать для более высокой совместимости (не все дистрибутивы * nix имеют bash в качестве оболочки по умолчанию (в некоторых есть ksh или ash, но большинство из них зависят от стандарта shдля работы). Более того, если bash специфичен или в скрипте не используются расширенные функции, тогда в качестве интерпретатора следует использовать 'sh' (это еще одна причина), так как он может обрабатывать скрипт самостоятельно
6
@ Chinggis6 Правда, плохой выбор слов на моей стороне.
Camusensei
25

[это команда (или встроенная в некоторые оболочки). Он должен быть отделен пробелом от предыдущего оператора:

elif [
choroba
источник
3
Его заменяет встроенный bash, но ваше сообщение все еще корректно. использовать, type -a [чтобы увидеть это.
Camusensei
Это также двоичный файл, который всегда казался мне странным.
mr.zog
4

Я бы порекомендовал вам взглянуть на основы кондиционирования в Bash.

Символ «[» является командой и должен иметь пробел перед ней. Если после вашего 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, если еще заявление

Джон Уолш
источник