Я получаю то, что ожидал, делая это в bash
:
[ "a" == "a" ] && echo yes
Это дало мне yes
.
Но когда я делаю это zsh
, я получаю следующее:
zsh: = not found
Почему одна и та же команда ( /usr/bin/[
) ведет себя по-разному в разных оболочках?
$PATH
поиска. и==
не действуетtest
синтаксис для/usr/bin/[
Анвэя. Просто=
в порядке.Ответы:
Этого нет
/usr/bin/[
ни в одном из снарядов. В Bash вы используете встроенную командуtest
/[
и аналогично в zsh .Разница в том, что zsh также имеет
=
расширение :=foo
расширяет путь кfoo
исполняемому файлу. Это означает,==
что вы пытаетесь найти команду, вызываемую=
в вашемPATH
. Поскольку эта команда не существует, вы получаете ошибкучто вы видели (и на самом деле, это то же самое произойдет, даже если вы на самом деле использовали
/usr/bin/[
).Вы можете использовать
==
здесь, если вы действительно хотите. Это работает, как вы ожидали в Zsh:потому что цитирование препятствует
=word
запуску расширения. Вы также можете отключить этуequals
опцию с помощьюsetopt noequals
.Тем не менее, вы бы лучше:
=
, POSIX-совместимый тест на равенство ; или[[
условные выражения==
в Bash и Zsh . В общем,[[
все лучше и безопаснее, в том числе избегая подобных проблем (и других), используя специальные правила синтаксического анализа внутри.источник
[
и[[
? (Поиск в Google[ vs [[
дает мне результатыvs
только, LOL)[[
поддерживает более широкий диапазон тестов в обоих случаях и имеет собственные правила синтаксического анализа, позволяющие избежать необходимости заключать в кавычки переменные, операторы и т. д. Если вы специально используете Bash или Zsh, используйте[[
. Если вы пишете портативный сценарий, запись в POSIX-совместимые[
/test
команды (которая может или не может быть реальной командой на вашей работающую системе).[[
там и забудьте о[
существовании.[[
по- другому способен. попробуйте это с этимfor f in *; do [ -e "$f" ] && for a in f d h p S b c; do [ "-$a" "$f" ] && for p in r w x u g; do [ "-$p" "$f" ] || p=-; a=$a$p; done && break; done && printf "%s:\t%s\n" "$a" "$f"; done
.=
/==
, возможно , один случай , когда[[
не лучше[
, так как[[ a == b ]]
это делает «а» соответствует «B» образец и не является «» равно «Ъ» , как и следовало ожидать. Это означает, что вам нужно написать,[[ $a == "$b" ]]
например. По крайней мере, с[
командой, если вы знаете, как работает синтаксический анализ команд, вы знаете, что вам нужно написать ее,[ "$a" = "$b" ]
чтобы предотвратить оператор split + glob, как в других командах. Имея это в виду и если вы не используете -a или -o,[
это безопасно в реализациях, соответствующих POSIX.И zsh, и bash дают один и тот же ответ (
type
тоже встроен для обеих оболочек):источник
[
встроенная команда оболочки в bash и zsh:Из документации команд Shell Builtin :
Официальная документация (
$ help test
) позволяет использовать только=
:Итак, правильное выражение будет:
То, что происходит, - то, что bash немного менее строг. Поддержка
==
оператора с[
расширением bash, похоже, не рекомендуется использовать:Если вы хотите использовать
==
, вы должны использовать[[
ключевое слово:Имейте в виду, что
[[
он менее переносим (это не POSIX). Но и bash, и zsh поддерживают это.источник
В обеих оболочках,
bash
иzsh
,[
утилита встроена в оболочку. Это реализация оболочки этого инструмента, она используется в предпочтении двоичному/usr/bin/[
. Разные результаты, с которыми вы сталкиваетесь, вызваны разными реализациями.В
bash
,[
утилита принимаетCONDITIONAL EXPRESSIONS
в качестве[[
составной команды. Согласно man-странице bashs оба=
и==
действительны:В
zsh
,[
утилита пытается реализовать POSIX и его расширения, где они указаны. В спецификации тестовой утилиты POSIX не существует==
оператор , определенный.источник