Я хочу представить несколько условий, как это:
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 показывает, если ....
Что не так с этим условием? Я думаю, что-то не так с ()
.
test
([
), а не оболочкой. Оболочка оценивает только состояние выхода[
.Ответы:
Классическая техника (метасимволы экранирования):
Я заключил ссылки
$g
в двойные кавычки; это хорошая практика, в общем. Строго говоря, скобки не нужны, потому что приоритет-a
и-o
делает его правильным даже без них.Обратите внимание , что
-a
и-o
операторы являются частью спецификации POSIX дляtest
ака[
, в основном для обратной совместимости (так как они были частьюtest
в 7 - е издание UNIX, например), но они явно помечены как «устаревающих» по стандарту POSIX. Bash (см. Условные выражения ), кажется, вытесняет классические значения-a
и значения POSIX для-o
своих собственных альтернативных операторов, которые принимают аргументы.С некоторой осторожностью вы можете использовать более современный
[[
оператор, но помните, что версии в Bash и Korn Shell (например) не обязательно должны быть идентичными.Пример запуска с использованием Bash 3.2.57 на Mac OS X:
Вам не нужно заключать переменные в кавычки,
[[
как вы это делаете,[
потому что это не отдельная команда, как это[
делается.Я бы так и подумал. Однако есть и другая альтернатива, а именно:
В самом деле, если вы прочитали рекомендации по «портативной оболочке» для
autoconf
инструмента или связанных пакетов, то эти обозначения - с использованием||
«и&&
» - это то, что они рекомендуют. Я полагаю, вы могли бы даже пойти так далеко:Там, где действия так же банальны, как и эхо, это неплохо. Когда блок действий, который должен повторяться, состоит из нескольких строк, повторение слишком болезненное, и предпочтительна одна из более ранних версий - или вам нужно заключить действия в функцию, которая вызывается в разных
then
блоках.источник
-a
самом деле имеет более высокий приоритет , чем-o
( в отличие ,&&
и||
в оболочке - однако, внутриbash
[[ ... ]]
условных ,&&
также имеет более высокий приоритет , чем||
). Если вы хотите избежать-a
и-o
для максимальной надежности и переносимости - что предлагает самаif ([ $g -eq 1 ] && [ "$c" = "123" ]) || ([ $g -eq 2 ] && [ "$c" = "456" ])
if test "$g" -eq 1 -a "$c" = "123" || test "$g" -eq 2 -a "$c" = "456"; then ...
&&
или||
также предпочтительнее, поскольку оно ведет себя больше как условные выражения в других языках и позволяет вам создавать условия короткого замыкания. Например:if [ -n "${check_inodes}" ] && [ "$(stat -f %i "/foo/bar")" = "$(stat -f %i "/foo/baz")" ]
. Делая это таким образом, еслиcheck_inodes
оно пустое, вы избегаете двух обращений кstat
, тогда как более сложное условие теста должно обрабатывать все аргументы перед выполнением (что также может привести к ошибкам, если вы забудете об этом поведении).В Баше:
источник
bash
. В качестве отступления: в данном конкретном случае скобки даже не нужны, потому что внутри[[ ... ]]
условных условий на&&
самом деле более высокий приоритет, чем||
- в отличие от таких условных выражений.if
/else
и иметь код между нимиthen
иfi
вставить функцию, чтобы избежать ее повторения. В очень простых случаях вы можете использоватьcase
оператор с;&
падением (в Bash 4).Использование
/bin/bash
следующего будет работать:источник
Будьте осторожны, если в строковых переменных есть пробелы, и вы проверяете существование. Обязательно процитируйте их правильно.
источник
источник
{ ;}
может быть использован вместоВ bash для сравнения строк вы можете использовать следующую технику.
Пример:
источник
источник
Вы также можете связать более 2 условий:
источник