Intereting Posts
Как использовать локальный IP-адрес вместо внешнего ln -s с дорогой относительно pwd SELinux вмешивается в совместное использование файлов хоста / гостевого компьютера с использованием KVM использование devtmpfs для / dev Как определить, когда оболочка принадлежит удаленному сеансу SSH? максимальное количество файлов ls может отображать Почему в моем $ PATH не используется первый исполняемый файл? Цветной текст, созданный с помощью PS1, и цветной вывод из команд путают друг друга notify-send не работает из сценария, но работает с терминала Почему tcpdump захватывает многие пакеты с помощью «(tcp-syn)! = 0», но не с «tcp & (tcp-syn)! = 0" Программно определить escape-код ANSI, поддерживаемый терминалом Присоединение к сети Kerberos не отвечает Как получить процент CPU в качестве счетчика? настроить доставку локальной почты пользователю из cron script Предоставьте пользователям root права на монтирование разделов NTFS

Сплошное поведение сравнения со стороны Solaris

Это застало меня врасплох!

У нас есть машина Solaris (версия: SunOS 5.8), где размещается ключевой сценарий / процесс, который работает много лет без жалоб. Недавно у нас появилась причина взглянуть под капот и найти условие испытания, которое, насколько я могу судить, не должно работать, но по какой-то причине:

$ sh $ [ 90% -gt 95 ]; echo $? 1 $ [ 96% -gt 95 ]; echo $? 0 

Какие?! Это, похоже, не случайность:

 $ [ 96% -lt 95 ]; echo $? 1 $ [ 96% -eq 96 ]; echo $? 0 

Это не просто % :

 $ [ 96blah -eq 96 ]; echo $? 0 $ [ 1.2 -gt 1 ]; echo $? 1 

Это похоже на SunOS 5.8, 5.9 и 5.10, но я раньше этого не замечал. К сожалению, у меня, похоже, нет другой системы, отличной от Solaris, чтобы проверить, нет ли /bin/sh символически привязанного к bash (что не так либерально с его интерпретацией).

Итак, неаккуратный код в сторону ( x% передается переменной и, вероятно, не был замечен), почему стандартная оболочка (предположительно Bourne?) Обрабатывает эти тестовые аргументы как целые числа, обрезая их? Это документированное поведение? Я ничего не видел в man sh но, возможно, что-то пропустил.

NB: На самом деле это было второстепенное boo-boo в другом странном тестовом состоянии, но это, вероятно, заслуживает собственного вопроса.

    В стандарте говорится, что тестовые операторы, такие как -gt сравнивают его операнды как целые числа, но в нем не упоминается, что должно произойти, когда поставленные строки не являются целыми числами. Таким образом, наблюдаемое поведение полностью корректно. BTW: он также совместим с историческим поведением UNIX.

    / bin / sh конечно не связано с bash, так как bash не является стандартным, достаточно совместимым и, вероятно, приведет к сбою большого количества скриптов.

    В 2010 году с развитием Solaris 10 / bin / sh был заменен на ksh93, и хотя ksh намного более совместим с Bourne Shell, чем bash, это вызвало у Solaris отсутствие / и / usr в разных файловых системах, которые были проблем нет. Обратите внимание, что ksh93 загружает динамические библиотеки из / usr.

    Поскольку я не могу отформатировать комментарий в намеченных строках, я использую форму ответа, чтобы объяснить мой комментарий о том, как получить оболочку POSIX.

    Официальным методом получения оболочки POSIX является:

     1) unset PATH # if you run an older Bourne Shell 2a) PATH=`getconf PATH` # this is with the Bourne Shell 2b) PATH=$(command -p getconf PATH) # this is with a Korn shell 3) sh # This starts a POSIX shell 

    Было несколько попыток стандартизации #!/path/to/shell но POSIX не имеет отношения к PATH, и по этой причине мы не смогли найти решение.

    Похоже, на это был дан ответ в комментариях: Solaris sh имеет причуды. По крайней мере, в прошлом это была даже не оболочка POSIX . (Шили указывает, что POSIX не требует, чтобы /bin/sh был POSIX sh , а это значит, что вам нужно перепрыгнуть через другое обруч, чтобы писать полностью переносимые сценарии оболочки.)

    Этот вопрос может содержать некоторую полезную информацию / ссылки: https://superuser.com/questions/125728/what-is-the-difference-between-bash-and-sh

    Ответ Шили указывает, что стандарт не указывает, что происходит с цифрами с завершающим мусором, поэтому ваш сценарий эффективно имеет неопределенное поведение и полагается на то, что делает Solaris sh . Таким образом, он не переносится.

    Такие вещи являются основной причиной, по которой, по-видимому, не рекомендуется использовать bash as /bin/sh в системе Solaris. Некоторые дистрибутивы GNU / Linux используют dash для /bin/sh , в то время как другие используют bash .

    Я проверил ваш код на 3 ракетах, которые я установил:

     bash 4.3-11ubuntu2 $ [ 96blah -eq 96 ]; echo $? bash: [: 96blah: integer expression expected 2 dash 0.5.7-4ubuntu1 $ [ 96blah -eq 96 ]; echo $? dash: 1: [: Illegal number: 96blah 2 busybox sh 1.22.0-9ubuntu1 $ [ 96blah -eq 96 ]; echo $? sh: 96blah: bad number 2