Вы получили это назад. /bin/shв наши дни почти никогда не является панцирем Борна, и именно тогда у вас возникает проблема, когда вы используете #! /bin/shудар.
Оболочка Борна была оболочкой, написанной в конце 70-х годов и заменившей предыдущую оболочку Томпсона (также называемую sh). В начале 80-х годов Дэвид Корн написал несколько расширений для оболочки Bourne, исправил несколько ошибок и смутил дизайн (и представил некоторые) и назвал ее оболочкой Korn.
В начале 90-х POSIX указывал sh язык на основе подмножества оболочки Korn, и большинство систем теперь изменили их /bin/shна либо оболочку Korn, либо оболочку, соответствующую этой спецификации. Что касается BSD, они постепенно меняли свою /bin/sh, первоначально (после того, как они больше не могли использовать оболочку Bourne по лицензионным причинам) оболочку Almquist, клон оболочки Bourne с некоторыми расширениями ksh, поэтому она стала POSIX-совместимой.
Сегодня все системы POSIX имеют оболочку sh(чаще всего, но не обязательно, в /binPOSIX не указывается путь к указанным утилитам), которая в основном совместима с POSIX. Обычно он основан на ksh88, ksh93, pdksh, bash, ash или zsh², но не на оболочке Bourne, поскольку оболочка Bourne никогда не была POSIX-совместимой3. Некоторые из этих оболочек ( bash, zsh, yashи некоторые pdkshпроизводные включить режим POSIX-совместимый при вызове , как shи в меньшей степени соответствует иным образом ).
bash(GNU-ответ на оболочку Korn) на самом деле является единственной оболочкой с открытым исходным кодом (и можно сказать, что поддерживается только в настоящее время, поскольку остальные, как правило, основаны на ksh88, который не получил никакой новой функции с 90-х годов), который был сертифицирован как быть POSIX-совместимым sh(как часть сертификации MacOS).
Когда вы пишете сценарий с #! /bin/sh -самоуверенностью, вы должны использовать стандартный shсинтаксис (а также использовать стандартный синтаксис для утилит, используемых в этом сценарии, если вы хотите быть переносимым, при интерпретации оболочки используется не только оболочка). script), тогда не имеет значения, какая реализация этого стандартного shсинтаксического интерпретатора используется ( ksh, bash...).
Неважно, что эти оболочки имеют расширения над стандартом, если вы их не используете. Это похоже на написание кода на C, если вы пишете стандартный код на C и не используете расширения одного компилятора (например gcc) или другого, ваш код должен компилироваться нормально, независимо от реализации компилятора, при условии, что компилятор совместим.
Здесь, с #! /bin/shона Взрыва, ваша главная задача будет системы , где /bin/shявляется Bourne оболочки , которая, например , не поддерживает стандартные функции , такие как $((1+1)), $(cmd), ${var#pattern}... В этом случае вам может понадобиться обходные как:
#! /bin/sh -
if false ^ true; then
# in the Bourne shell, ^ is an alias for |, so false ^ true returns
# true in the Bourne shell and the Bourne shell only.
# Assume the system is Solaris 10 (older versions are no longer maintained)
# You would need to adapt if you need to support some other system
# where /bin/sh is the Bourne shell.
# We also need to fix $PATH as the other utilities in /bin are
# also ancient and not POSIX compatible.
PATH=`/usr/xpg6/bin/getconf PATH`${PATH:+:}$PATH || exit
export PATH
exec /usr/xpg4/bin/sh "$0" "$@"
# that should give us an environment that is mostly compliant
# to the Single UNIX Specification version 3 (POSIX.2004), the
# latest supported by Solaris 10.
fi
# rest of the script
Кстати, Ubuntu /bin/shне bashпо умолчанию. В dashнаши дни это оболочка на основе NetBSD sh, сама основанная на оболочке Almquist, которая в основном совместима с POSIX, за исключением того, что она не поддерживает многобайтовые символы. В Ubuntu и других систем Debian на базе, вы можете выбрать между bashи dashдля /bin/shс dpkg-reconfigure dash) 4 . shСценарии, поставляемые с Debian, должны работать одинаково в обеих оболочках, так как они написаны в стандарте политики Debian (расширенный набор стандарта POSIX). Вы , вероятно, обнаружите , что они также работают КИ в zsh«S shэмуляции или bosh(вероятно , не , ksh93ни , yashкоторые не имеет localвстроенной команды (требуется политика Debian , но не POSIX)).
Все системы в unix.stackexchange.com имеют sh где-то POSIX . Большинство из них имеют /bin/sh(вы можете найти очень редкие, у которых нет /binкаталога, но вы, вероятно, не заботитесь об этом), и это, как правило, shинтерпретатор POSIX (а в редких случаях (нестандартная) оболочка Bourne вместо этого). ).
Но shэто единственный исполняемый файл интерпретатора оболочки, который вы наверняка найдете в системе. Для других оболочек вы можете быть уверены, что MacOS, Cygwin и большинство дистрибутивов GNU / Linux будут иметь bash. Производные от SYSV ОС (Solaris, AIX ...) обычно имеют ksh88, возможно, ksh93. OpenBSD, MirOS будет иметь производную от pdksh. MacOS будет иметь zsh. Но от этого не будет никакой гарантии. Никакой гарантии того, будет ли установлен bashили нет какой-либо из этих других корпусов в /binили где-либо еще (это обычно встречается в /usr/local/binBSD, например, при установке). И, конечно, нет гарантии, какая версия оболочки будет установлена.
Обратите внимание, что #! /path/to/executableэто не соглашение , это особенность всех Unix-подобных ядер ( представленных в начале 80-х годов Деннисом Ритчи ), которая позволяет выполнять произвольные файлы, указав путь к интерпретатору в первой строке, начиная с #!. Это может быть любой исполняемый файл.
При выполнении файла, первой строка начинается с #! /some/file some-optional-arg, ядро заканчивает выполнение /some/fileс some-optional-arg, путем сценария и исходными аргументами в качестве аргументов. Вы можете сделать эту первую строку, #! /bin/echo testчтобы увидеть, что происходит:
$ ./myscript foo
test ./myscript foo
Когда вы используете /bin/sh -вместо /bin/echo test, ядро выполняет /bin/sh - ./myscript foo, shинтерпретирует код содержимого, хранящийся в, myscriptи игнорирует эту первую строку, поскольку это комментарий (начинается с #).
¹ Вероятно, единственная система сегодня, где кто-либо из нас сталкивался с системой /bin/sh, основанной на оболочке Bourne, - это Solaris 10. Solaris является одним из немногих Unix, которые решили сохранить там оболочку Bourne для обратной совместимости ( shязык POSIX не полностью обладает обратной совместимостью с оболочкой Bourne) и (по крайней мере, для настольных систем и полных серверов) имеет POSIX в shдругом месте (на /usr/xpg4/bin/shоснове ksh88), но это изменилось в Solaris 11, где /bin/shтеперь находится ksh93. Другие в основном несуществующие.
² из MacOS / X , используемый , чтобы быть , но позже изменено на . Это не основной фокус для использования в качестве реализации POSIX . Его режим в первую очередь для возможности вставлять или вызывать ( ) код POSIX в скриптах/bin/shzshbashzshshshsourceshzsh
³ Недавно @schily расширила оболочку OpenSolaris (основанную на оболочке SVR4, основанную на оболочке Bourne), чтобы она стала совместимой с POSIX, boshно я не знаю, используется ли она в любой системе. Наряду с ksh88этим делает его второй POSIX-совместимой оболочкой на основе кода оболочки Bourne.
4 В более старых версиях вы также можете использовать mkshили более lkshинкарнацию POSIX . Это оболочка MirOS (ранее MirBSD), основанная на pdksh, сама основанная на оболочке Forsyth (еще одно повторное воплощение оболочки Bourne))