Как правильно играть с тестовой командой? - PullRequest
2 голосов
/ 29 мая 2010
[root@jiaoyou ~]# test 1 = 1 -a 0 = 1
[root@jiaoyou ~]# if [1 = 1 -a 0 = 1]then echo 1;else echo 2;fi
-bash: syntax error near unexpected token `else'

Почему test не дает никакого вывода, а оператор if не выполняется?

Может кто-нибудь указать, что здесь не так?

ОБНОВЛЕНИЕ

Может кто-нибудь проиллюстрировать, как имитировать сложные выражения, такие как 1=1 and (0=1 or 1=1) с [[?

Ответы [ 3 ]

4 голосов
/ 29 мая 2010

Коды возврата не печатаются; Вы должны повторить значение $?, чтобы увидеть его.

[ - это команда. Так же, как вы не пишете echoHelloworld, вы не можете писать [1 ....

1 голос
/ 31 мая 2010

Есть несколько эквивалентных способов выполнения теста, который вы ищете. Во-первых, по сути, так, как вы это делаете, но с фиксированным синтаксисом (добавлены необходимые пробелы вокруг параметров в команду [ (aka test) и ; между ] и then) :

if [ 1 = 1 -a 0 = 1 ];then echo 1;else echo 2;fi

Вот версия с явной группировкой в ​​выражении; обратите внимание, что скобки нужно экранировать, потому что они являются специальными символами в оболочке, но в этом случае мы хотим, чтобы они передавались команде [ в качестве аргументов:

if [ \( 1 = 1 \) -a \( 0 = 1 \) ];then echo 1;else echo 2;fi

Другая версия с явной группировкой, на этот раз с использованием двух отдельных команд [, связанных с оператором bash && (обратите внимание, что это также может подключать другие команды):

if [ 1 = 1 ] && [ 0 = 1 ];then echo 1;else echo 2;fi

И, наконец, пара примеров, использующих оператор bash [[ вместо команды [; обратите внимание, что [[ не является командой, поэтому ее выражение не анализируется как аргументы команды, что позволяет использовать его более интуитивно понятный синтаксис (например, допускает && и || в качестве операторов, скобки и !<> сравнения без экранирования ):

if [[ 1 = 1 && 0 = 1 ]];then echo 1;else echo 2;fi
if [[ ( 1 = 1 ) && ( 0 = 1 ) ]];then echo 1;else echo 2;fi

Еще несколько замечаний / предупреждений: оператор =, используемый во всех этих примерах, выполняет сравнение строк, а не числовое сравнение (т. Е. [ 1 = 01 ] является ложным); если вы хотите числовое сравнение, используйте вместо него -eq (аналогично, < и > - сравнения строк, в то время как -lt и -gt - числовые). Кроме того, если вы сравниваете строки, содержащие пробелы, '[' может ошибочно принять строку за часть выражения при некоторых обстоятельствах (особенно если строки не заключены в двойные кавычки); насколько я знаю [[ никогда не было этой проблемы. В целом, если вы используете оболочки, поддерживающие [[, гораздо проще иметь дело, чем [.

0 голосов
/ 29 мая 2010

Как правильно утверждает @ IgnacioVazquez-Abrams, test просто устанавливает код ошибки.

Тем не менее, вот хороший bash-ism для быстрой проверки значения ошибки:

test [ expr ] && echo SUCCESS || echo FAIL

Из-за короткого замыкания && и || это будет выдавать SUCCESS или FAIL в зависимости от того, вернется ли тест 0 или не равен 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...