Когда sh является символической ссылкой на bash или dash, bash ограничивается POSIX-совместимостью, поэтому он должен быть на 100% совместим с sh?

8

Из разницы между bash и sh :

Возьмем вопрос: если у вас есть /bin/shссылка на bash, то bash не будет вести себя так же, когда /bin/shвызывается так же, как при вызове as /bin/bash. Когда он вызывается как sh, он ограничивается в основном POSIX-совместимостью и ограниченным набором расширений.

Означает ли это, что всякий раз, когда я сталкиваюсь со сценарием оболочки в Linux с символом sh: « #!/bin/shдаже если в этом дистрибутиве bin/shесть символическая ссылка на другую оболочку, такую ​​как dash или bash, она должна быть на 100% совместима с оболочкой bourne, поскольку ограничить себя ограниченным набором расширений? Чтобы я мог выполнить их во FreeBSD? Есть ли исключения из этого? Или я должен с уверенностью предположить, что это будет работать?

Так что, если в дистрибутиве bin/shесть символьная ссылка bin/bashи сценарий использования #!/bin/shи сценарий содержат bashism, он не будет работать, так как bash будет находиться в режиме sh?

user1115057
источник

Ответы:

16

Нет, если /bin/shэто символическая ссылка на bash, то bash входит только в режим posix - от man bash :

Когда вызывается как sh, bash переходит в режим posix после чтения файлов запуска.

Если вы теперь будете искать режим posix на странице руководства bash, вы увидите, что некоторые встроенные оболочки похожи timeили sourceведут себя по-разному. Это все. bashishms, такие как запись functionперед объявлением функции или использование sourceвместо, .все еще будут работать, но команды могут вести себя по-разному.

Так что, если /bin/shэто символическая ссылка на /bin/bashвсе типичные bashishms все еще работают.

Для довольно обширного списка отличий в режиме Posix посмотрите справочное руководство bash .

Ульрих Дангел
источник
Поэтому я думаю, что лучше всего протестировать весь скрипт в инструменте checkbashism. Я слышал, что некоторые дистрибутивы, такие как Debian и Ubuntu (для этого нужно подтверждение), теперь имеют символическую ссылку bin / sh для тире. Совместим ли dash с оболочкой Bourn? Если да, то, по крайней мере, все сценарии оболочки Debian и Ubuntu должны работать под FreeBSD.
user1115057
@ user1115057 только сценарии оболочки с /bin/shименем shebang. Сценарий оболочки все еще может явно использовать /bin/bash. В любом случае, большинство сценариев оболочки, вероятно, будут нормально работать в / bin / sh, но проблема заключается в пользовательских инструментах, например, большинство сценариев оболочки ожидают пользовательского пространства GNU, что, вероятно, будет большей проблемой, чем просто некоторая синтаксическая ошибка. Я также добавил ссылку на ссылку на bash, в которой перечислено различное поведение в режиме posix
Ульрих Дангел
Итак, из того, что я прочитал, BSD использует ash в качестве bin / sh, в то время как Debian и Ubuntu используют dash. Если эти оболочки совместимы, это означает, что у меня больше не будет проблем с shebang #! / Bin / sh. Но, как вы сказали, будет другая проблема, связанная с пользовательским
пространством
@ user1115057 тире также не идеален, например, wiki.ubuntu.com/DashAsBinSh/#echo в любом случае большинство сценариев оболочки довольно просты и могут быть легко портированы… удачи
Ульрих Дангел
Но тире и пепел совместимы, верно?
user1115057
8

Кажется, есть некоторая путаница вокруг оболочки Борна. Оболочка Bourne была оболочкой Unix десятилетия назад, во времена до POSIX. В настоящее время «sh» является реализацией или другой оболочкой, которая реализует спецификацию POSIX, среди которых есть bash, pdksh, AT & T ksh, более новые оболочки Almquist и их производные, которые стали совместимыми с POSIX (включая «sh» некоторых BSD остальные BSD основаны на pdksh и Debian ash (dash)). Даже у Zsh есть режим, в котором он в основном соответствует POSIX.

Оболочка Bourne не совместима с POSIX и в настоящее время не встречается во многих системах. Где оболочка Bourne найдена или где ее нет, всегда будет "sh", который соответствует POSIX (и не будет оболочкой Bourne), обычно в /binто время как заметным (раздражающим) исключением является Solaris.

Обратите внимание, что до появления оболочки Борна, о которой мы говорим более 30 лет назад, «sh» была оболочкой Томпсона. Мы больше не пишем сценарии, совместимые с оболочкой Томпсона. Точно так же мы должны перестать думать о «ш» как о оболочке Борна.

Теперь «sh» - это спецификация, а не много когда-нибудь несовместимых вариантов реализации. Это значительно облегчает написание переносимых скриптов. Просто следуйте спецификации .

Это касается "sh" и всех стандартных утилит (sed, cut, tr ...)

Стефан Шазелас
источник
+1 за «напиши в спецификацию». Но, к сожалению, этого часто недостаточно для мобильности. Например, что если вы захотите использовать шаблоны egrep в стиле sed? Спецификация не предусматривает этого. В системах с утилитами на основе Gnu (или BusyBox) вы используете sed -r. В системах с утилитами на основе BSD вы используете sed -E. Sed FreeBSD принимает оба, но Mac OS X принимает только -E. И так далее, и так далее.
dubiousjim
Это не относится к делу. Спецификация не предоставляет его, поэтому вы не можете использовать его переносимо / POSIXly. Если вы используете BRE, это будет работать на всех POSIX-совместимых системах, это гарантия, предоставляемая POSIX, поэтому она полезна. Как вы говорите, вне POSIX нет надежды, поскольку seds либо не поддерживает ERE, либо поддерживает его с другой опцией или другим синтаксисом ERE. Обратите внимание, что ERE менее способны, чем BRE (в ERE расширен только синтаксис, чтобы сэкономить некоторую типизацию. ERE могут быть переведены в BRE, обратное неверно (BRE не \(...\)\1имеет перевода в стандартных ERE).
Стефан Шазелас
1
Я понимаю, что (POSIX) ERE не имеют обратных ссылок; на самом деле я принимал участие в редактировании этой части стандарта. Неправильно, что PREIX ERE строго менее способны, чем BRE, поскольку в текущем стандарте чередование не определено для BRE. Тем не менее, я не знаю ни одного движка регулярных выражений, который не \|поддерживает BRE. Я за то, чтобы писать как можно более мобильно. Я только делал (я думал, что это высоко ценится) наблюдение, что это может быть болезненным, и иногда запись в POSIX просто невозможна. Где-то есть ссылки, которые показывают много таких извращений; буду искать их.
dubiousjim
Хороший вопрос об чередовании, я забыл об этом и исправлюсь. С sed это вряд ли будет блокировать, так как вы можете использовать несколько выражений для соответствия альтернативным регулярным выражениям. В стандартном наборе инструментов есть awk, который можно использовать, если нужны ERE. Я очень редко оказываюсь со стандартным инструментарием, и когда я это делаю, обычно бывает так, что другой язык, такой как perl, более уместен, но я понимаю вашу точку зрения (хотя я все еще думаю, что это не относится к теме в этой теме о написании переносимых скриптов)
Стефан Шазелас
Пример, который я придумал не по порядку: строки shebang (вверху каждого сценария оболочки) не указаны в POSIX. Кроме того, я не уверен, что когда-либо использовал систему, которая была на 100% POSIX-совместимой. Например, POSIX говорит, что вы можете включать в себя переводы строк, ${VAR:=stuff...here}но многие оболочки не позволяют вам, вы должны заключать в кавычки stuff...here.
dubiousjim