Почему `==` по-разному ведет себя внутри `[…]` в zsh и bash?

Ваш почтовый ящик, вероятно, поврежден или какой-то почтовый клиент оставил в нем остаток байта / символа. Другой почтовый клиент может даже сказать, что он пустой.

Поскольку он пуст, проще удалить его с помощью команды:

rm /var/spool/mail/psms1

Таким образом, он будет воссоздан в следующий раз, когда вы получите сообщение, и команда mail будет довольна с этим.

9
16.01.2016, 01:27
4 ответа

Это не / usr / bin / [ в любой из оболочек. В Bash вы используете встроенный тест / [ команду и аналогично в zsh .

Разница в том, что zsh также имеет расширение = : = foo расширяется до пути к исполняемому файлу foo . Это означает, что == рассматривается как попытка найти команду с именем = в вашем PATH . Поскольку этой команды не существует, вы получите ошибку

 zsh: = not found 
 

, которую вы видели (и на самом деле то же самое произойдет, даже если вы действительно использовали / usr / bin / [).


Вы можете использовать здесь == , если действительно хотите. В zsh:

[ "a" "==" "a" ] && echo yes

это работает так, как вы ожидали, потому что кавычки предотвращают запуск раскрытия = word . Вы также можете отключить параметр равно с помощью setopt noequals .


Однако вам будет лучше:

  • Использование single = , POSIX-совместимого теста на равенство ; или
  • Еще лучше, с использованием [ условных выражений с == в обоих Bash и zsh . В общем, [ лучше и безопаснее во всех отношениях, в том числе позволяет избежать такого рода проблем (и других) за счет наличия внутри специальных правил синтаксического анализа.
18
27.01.2020, 20:04

И zsh, и bash дают одинаковый ответ ( тип тоже встроен в обе оболочки):

$ type -a [
[ is a shell builtin
[ is /usr/bin/[
2
27.01.2020, 20:04

В обеих оболочках, bash и zsh , утилита [ является встроенной оболочкой. Это реализация этого инструмента в оболочке, она используется вместо двоичного файла / usr / bin / [. Различные результаты, с которыми вы сталкиваетесь, вызваны разными реализациями.


В bash утилита [ принимает УСЛОВНЫЕ ВЫРАЖЕНИЯ как составную команду [[]. Согласно странице руководства bashs допустимы как = , так и == :

string1 == string2
string1 = string2
        True if the strings are equal.  = should be used with the test command for POSIX
        conformance.

В zsh утилита [ пытается реализовать POSIX и его расширения, если они указаны. В спецификации тестовой утилиты POSIX не определен оператор == .

1
27.01.2020, 20:04

[] является встроенной командой оболочки в bash и zsh:

$ type [
[ is a shell builtin

Из документации Встроенные команды оболочки:

Встроенные команды содержатся в самой оболочке. Когда имя встроенной команды используется в качестве первого слова простой команды (см. Простые команды), оболочка выполняет команду напрямую, не вызывая другую программу. Встроенные команды необходимы для реализации функциональности, которую невозможно или неудобно получить с помощью отдельных утилит.

Официальная документация ($ help test) разрешает использовать только =:

STRING1 = STRING2

Истинно, если строки равны.

Таким образом, правильным выражением будет:

$ [ "a" = "a" ] && echo yes
yes

Что происходит, так это то, что bash немного менее строг. Поддержка оператора == с помощью [кажется расширением bash, и использовать его не рекомендуется:

string1 == string2

string1 = string2

Истинно, если строки равны. При использовании с командой [[ выполняет сопоставление с образцом, как описано выше (см. Условные конструкции).

'=' следует использовать с командой test для соответствия POSIX.

Если вы хотите использовать ==, вам следует использовать ключевое слово [[:

$ [[ "a" == "a" ]] && echo yes
yes

Имейте в виду, что [[[ менее переносимо (не является POSIX). Но и bash, и zsh поддерживают его.

2
27.01.2020, 20:04

Теги

Похожие вопросы