Как представить несколько условий в операторе if оболочки?
Я хочу представить несколько условий такой:
if [ ( $g -eq 1 -a "$c" = "123" ) -o ( $g -eq 2 -a "$c" = "456" ) ]
then
echo abc;
else
echo efg;
fi
но когда я выполняю скрипт, он показывает
syntax error at line 15: `[' unexpected,
где строка 15 показывает, если ....
что не так с этим условием? Я думаю, что-то не так с ().
6 ответов:
классическая техника (escape metacharacters):
if [ \( "$g" -eq 1 -a "$c" = "123" \) -o \( "$g" -eq 2 -a "$c" = "456" \) ] then echo abc else echo efg fiя приложил ссылки на
$gв двойных кавычках; это хорошая практика, в общем. Строго говоря, скобки не нужны, потому что приоритет-aи-oделает это правильно даже без них.отметим, что
-aи-oоператоры являются частью спецификации POSIX дляtest, иначе[, главным образом для обратной совместимости (так как они были частьюtestв 7-м издании UNIX, например), но они явно помечены как "устаревшие" POSIX. Баш (см. условные выражения) кажется, чтобы вытеснить классические и POSIX значения для-aи-oсо своими альтернативными операторами, которые принимают аргументы.
С некоторой осторожностью, вы можете использовать более современный
[[оператор, но имейте в виду, что версии в оболочке Bash и Korn (например) не должны быть идентичный.for g in 1 2 3 do for c in 123 456 789 do if [[ ( "$g" -eq 1 && "$c" = "123" ) || ( "$g" -eq 2 && "$c" = "456" ) ]] then echo "g = $g; c = $c; true" else echo "g = $g; c = $c; false" fi done doneпример выполнения, используя Bash 3.2.57 на Mac OS X:
g = 1; c = 123; true g = 1; c = 456; false g = 1; c = 789; false g = 2; c = 123; false g = 2; c = 456; true g = 2; c = 789; false g = 3; c = 123; false g = 3; c = 456; false g = 3; c = 789; falseне нужно цитировать переменные в
[[как вы делаете с[потому что это не отдельная команда таким же образом, что[есть.
разве это не классический вопрос?
я бы так и думал. Однако есть и другая альтернатива, а именно:
if [ "$g" -eq 1 -a "$c" = "123" ] || [ "$g" -eq 2 -a "$c" = "456" ] then echo abc else echo efg fiдействительно, если Вы читаете " портативный shell ' руководящие принципы для
autoconfинструмент или связанные пакеты, эта нотация-с помощью '||' и '&&' - это то, что они рекомендуют. Я полагаю, вы могли бы даже зайти так далеко, как:if [ "$g" -eq 1 ] && [ "$c" = "123" ] then echo abc elif [ "$g" -eq 2 ] && [ "$c" = "456" ] then echo abc else echo efg fiгде действия столь же тривиальны, как эхо, это не плохо. Когда блок действий, который нужно повторить, состоит из нескольких строк, повторение слишком болезненно, и одна из более ранних версий предпочтительнее - или вам нужно обернуть действия в функцию, которая вызывается в другом
thenблоки.
используя
/bin/bashследующие работы:if [ "$option" = "Y" ] || [ "$option" = "y" ]; then echo "Entered $option" fi
$ g=3 $ c=133 $ ([ "$g$c" = "1123" ] || [ "$g$c" = "2456" ]) && echo "abc" || echo "efg" efg $ g=1 $ c=123 $ ([ "$g$c" = "1123" ] || [ "$g$c" = "2456" ]) && echo "abc" || echo "efg" abc
будьте осторожны, если у вас есть пробелы в строковых переменных и проверить наличие. Обязательно цитируйте их правильно.
if [ ! "${somepath}" ] || [ ! "${otherstring}" ] || [ ! "${barstring}" ] ; then
#!/bin/bash current_usage=$( df -h | grep 'gfsvg-gfslv' | awk {'print '} ) echo $current_usage critical_usage=6% warning_usage=3% if [[ ${current_usage%?} -lt ${warning_usage%?} ]]; then echo OK current usage is $current_usage elif [[ ${current_usage%?} -ge ${warning_usage%?} ]] && [[ ${current_usage%?} -lt ${critical_usage%?} ]]; then echo Warning $current_usage else echo Critical $current_usage fi
Comments