Мое первое предположение состоит в том, что это будет выполняться правильно с большинством (или всеми) оболочками типа Bourne , пока первое выражение оценивает значение true.Это ожидаемое поведение, поскольку &&
и ||
фактически закорачивают выполнение: т. Е. В a || b
часть b не оценивается, если a истинно.
Примите во внимание следующее:
% for sh in ash bash ksh zsh;do
printf 'running %s with id %d\n\n' "$sh" 0
"$sh" -c 'file_id=0;[ "${file_id}" -eq 0 ] || oops'
done
running ash with id 0
running bash with id 0
running ksh with id 0
running zsh with id 0
% for sh in ash bash ksh zsh;do
printf 'running %s with id %d\n\n' "$sh" 1
"$sh" -c 'file_id=1;[ "${file_id}" -eq 0 ] || oops'
done
running ash with id 1
ash: oops: not found
running bash with id 1
bash: oops: command not found
running ksh with id 1
ksh: oops: not found
running zsh with id 1
zsh:1: command not found: oops
Более того, вы не можете набирать то, что хотите, в правой части короткозамкнутого выражения, потому что синтаксический анализатор попытается проанализировать всю строку, прежде чем выполнить ее (т. Е. Потерял место метасимвол вызовет ошибку)
% ksh -c 'id=0; [ "$id" -eq 0 ] || )'
ksh: syntax error: ')' unexpected
Обратите также внимание, что до тех пор, пока выполнение команды (встроенной или внешней) откладывается, оболочка не может знать, является ли она действительной или нет.Напротив, синтаксис зарезервированных слов оболочки и позиции метасимволов известны во время разбора:
% ksh -c 'type [ [[;id=0; [ "$id" -eq 0 ] || [[ '
ksh: syntax error: unexpected EOF
% ksh -c 'type [ [[;id=0; [ "$id" -eq 0 ] || [ '
[ is a shell builtin
[[ is a reserved word