Что значит быть «совместимым с sh»?

63

Я видел фразу «совместимость с sh», обычно используемую в отношении оболочек. Я не уверен, относится ли это также к программам, которые могут запускаться из оболочек.

Что означает, что оболочка или другая программа является "совместимой с sh"? Что бы это значило быть "несовместимым"?

Редактировать: Этот вопрос, задающий разницу между bash и sh, очень актуален: разница между sh и bash

Я все еще хотел бы прямого ответа на то, что значит быть "совместимым с sh". Можно предположить, что «совместимый с sh» означает «реализующий язык команд оболочки», но тогда почему существует так много «совместимых с sh» оболочек и почему они отличаются?

Praxeolitic
источник
1
Для сценария оболочки это указывает, использует ли этот сценарий синтаксис, совместимый (выполняемый) с Bourne Shell ( sh). Для другой оболочки это означает, может ли эта оболочка запускать сценарии оболочки Bourne.
HalosGhost
Если вы хотите узнать изобретателя снарядов, вы можете посетить мой ответ по адресу unix.stackexchange.com/questions/45684/…
PersianGulf

Ответы:

116

Почему существует так много "sh совместимых" оболочек?

Оболочки Борна был первым публично выпущен в 1979 году как часть Unix V7 . Поскольку практически каждая Unix и Unix-подобная система происходит от V7 Unix - даже если только духовно - оболочка Bourne была с нами «всегда».

Оболочка Bourne фактически заменила более раннюю оболочку, ретронимированную оболочкой Томпсона , но это произошло так рано в истории Unix, что сегодня о ней почти забыли. Оболочка Борна является надмножеством оболочки Томпсона.

Обе скважины Борна и Томпсона были названы sh. Оболочки определяется POSIX также называется sh. Таким образом, когда кто-то говорит « shсовместимость», они невольно ссылаются на эту серию оболочек. Если бы они хотели быть конкретными, они сказали бы «оболочка POSIX» или «оболочка Борна».

POSIX оболочки основан на версии 1988 KornShell , который , в свою очередь, означало , чтобы заменить Bourne Shell на AT & T Unix, перепрыгнуть в BSD C оболочки с точки зрения features.⁴ до такой степени , что kshявляется предком POSIX оболочки, наиболее Unix и Unix-подобные системы включают какой-то вариант оболочки Korn сегодня. Исключение составляют, как правило, крошечные встроенные системы, которые не могут предоставить место, которое занимает полная оболочка POSIX.

Тем не менее, оболочка Korn - в отличие от оболочки POSIX - никогда по-настоящему не становилась популярной вне коммерческого мира Unix. Это связано с тем, что его рост соответствовал ранним годам коммерциализации Unix, поэтому он оказался втянутым в войны Unix . BSD Unixes отказались от нее в пользу оболочки C, и ее исходный код не был свободно доступен для использования в Linux, когда он только начинался. Итак, когда первые дистрибьюторы Linux начали искать командную оболочку для своего ядра Linux, они обычно выбирают GNU Bash , один из тех - shсовместимых, о которых вы говорите.

Это ранняя связь между Linux и Баш в значительной степени опечатали судьбу многих других оболочек, в том числе ksh, cshи tcsh. Сегодня эти снаряды по-прежнему используют несгибаемые врачи, но они в меньшинстве ».

Вся эта история объясняет , почему создатели относительных опоздавших , как bash, zsh, и yashрешил сделать их sh-Совместим: Совместимость / POSIX Bourne минимальная оболочка для Unix-подобных систем должны обеспечить, чтобы получить широкое распространение.

Во многих системах по умолчанию используются интерактивные командные оболочки и /bin/shэто разные вещи. /bin/shможет быть:

  • Оригинальная оболочка Bourne. Это распространено в старых системах UNIX®, таких как Solaris 10 (выпущенный в 2005 году) и его предшественниках.

  • POSIX-сертифицированная оболочка. Это распространено в более новых системах UNIX®, таких как Solaris 11 (2010).

  • Оболочки Альмквист . Это клон оболочки с открытым исходным кодом Bourne / POSIX, первоначально выпущенный в Usenet в 1989 году , который затем был внесен в CSRG Беркли для включения в первый выпуск BSD, не содержащий исходного кода AT & T, 4.4BSD-Lite . Оболочка Almquist часто вызывается ash, даже если установлена ​​как /bin/sh.

    4.4BSD-Lite, в свою очередь, стал основой для всех современных производных BSD, /bin/shоставаясь в большинстве случаев производным Альмквиста, за одним важным исключением, отмеченным ниже. Вы можете увидеть это прямое потомство в репозиториях исходного кода для NetBSD и FreeBSD : они поставляли производную оболочки Almquist с первого дня.

    За ashпределами мира BSD есть две важные вилки:

    1. dash, принятый Debian и Ubuntu в 2006 году в качестве /bin/shреализации по умолчанию . (Bash остается интерактивной командной оболочкой по умолчанию в производных Debian.)

    2. ashКоманды в BusyBox , который часто используются во встраиваемых дистрибутивах Linux и может быть использована для реализации /bin/sh. Так как postdates dashи был получен из старого Debian в ashпакете , я решил считать его производным , dashа не ash, несмотря на свое название команды в BusyBox.

      (BusyBox также включает в себя менее функциональную альтернативу ashвызванному hush. Обычно только один из двух будет встроен в любой заданный двоичный файл BusyBox: ashпо умолчанию, но hushкогда пространство действительно ограничено. Таким образом, /bin/shв системах на основе BusyBox это не всегда dashпохоже.)

  • GNU Bash , который отключает большинство своих не-POSIX-расширений при вызове какsh .

    Этот выбор типичен для настольных и серверных вариантов Linux, за исключением Debian и его производных. Mac OS X также делает это со времен Panther, выпущенного в 2003 году.

  • Оболочка с ksh93расширениями POSIX , как в OpenBSD . Хотя оболочка OpenBSD изменяет поведение, чтобы избежать синтаксической и семантической несовместимости с оболочками Bourne и POSIX при вызове as sh, она не отключает ни одно из своих чистых расширений, которые не конфликтуют со старыми оболочками.

    Это не распространено; Вы не должны ожидать ksh93особенностей в /bin/sh.

Я использовал «сценарий оболочки» выше как общий термин, означающий сценарии оболочки Bourne / POSIX. Это связано с повсеместностью семейных раковин Борна. Чтобы говорить о сценариях на других оболочках, вам нужно дать классификатор, такой как «сценарий оболочки C». Даже в системах, где оболочка семейства C является интерактивной оболочкой по умолчанию, для сценариев лучше использовать оболочку Bourne.

Это говорит о том, что когда Википедия классифицирует оболочки Unix , они группируют их в совместимые с оболочкой Bourne, совместимые с оболочкой C и «другие».

Эта диаграмма может помочь:

Оболочки Unix: семейства Bourne, Korn, POSIX, C и rc Shell

(Щелкните для версии SVG, 31 КБ или для просмотра полноразмерной версии PNG , 218 КБ.)

Что бы это значило быть "несовместимым"?

Кто-то, говорящий о shнесовместимой вещи, обычно означает одну из трех вещей:

  1. Они имеют в виду одну из этих «других» оболочек.

  2. Они делают различие между семействами оболочек Bourne и C.

  3. Они говорят о некоторой специфической особенности в одной оболочке семейства Борнов, которой нет во всех других оболочках семейства Борнов. ksh93, bashИ , zshв частности , имеет много особенностей , которые не существуют в старых «стандартных» оболочках. Эти три также несовместимы во многих отношениях, как только вы выйдете за пределы общего POSIX / ksh88базы.

Классическая ошибка - писать сценарий оболочки с #!/bin/sh линией шебанга вверху, но использовать внутри него расширения оболочки Bash или Korn. Так /bin/shкак в наши дни это одна из оболочек в приведенной выше схеме семейства Korn / POSIX на очень многих системах, такие сценарии будут работать в той системе, в которой они написаны, но затем завершатся с ошибкой в ​​системах, где /bin/shесть нечто из более широкого семейства оболочек Bourne. Лучше всего использовать #!/bin/bashили #!/bin/kshубивать строки, если скрипт использует такие расширения.

Есть много способов проверить, является ли данный сценарий оболочки семейства Борнов переносимым:

  • Запустите checkbashismsна нем инструмент из проекта Debian, который проверяет сценарий на « bashisms ».

  • Запустите его posh, оболочку в репозитории пакетов Debian, которая нарочно реализует только функции, указанные в SUS3 , плюс несколько других незначительных функций .

  • Запустите его oshиз проекта Schily Tools , улучшенной версии оболочки Bourne, открытой для Sun в 2005 году в составе OpenSolaris, что делает его одним из самых простых способов получить оболочку Bourne стиля 1979 года на современном компьютере.

    В дистрибутив Schily Tools также входит boshоболочка типа POSIX с множеством нестандартных функций , но она может быть полезна для проверки совместимости сценариев оболочки, предназначенных для запуска на всех оболочках семейства POSIX. Это имеет тенденцию быть более консервативными в набор функций , чем bash, zshи улучшенных версий ksh93.

    Schily Tools также включает оболочку под названием bsh, но это историческая странность, которая вовсе не является оболочкой семейства Борнов.

  • Прочтите главу « Программирование в Portable Shell» в руководстве по GNU Autoconf . Вы можете распознать некоторые проблемные конструкции, о которых говорится в ваших скриптах.

Почему они разные?

По тем же причинам все "New & Improved!" вещи разные

  • Улучшенная версия может быть улучшена только путем нарушения обратной совместимости.

  • Кто-то думал о другом способе работы чего-то, что им нравится больше, но не то, что работал старый.

  • Кто-то пытался переопределить старый стандарт, не понимая его полностью, поэтому они испортили и создали непреднамеренную разницу.


Сноски и предложения :

  1. Ранние версии BSD Unix были просто дополнительными коллекциями программного обеспечения для V6 Unix. Поскольку оболочка Bourne не добавлялась в AT & T Unix до V7, технически BSD изначально не имела оболочки Bourne. Ответ BSD на примитивную природу оболочки Томпсона был C-оболочкой .

    Тем не менее, первые версии автономная из BSD (2.9BSD и 3BSD) были основаны на V7 или его преемнике портативного UNIX / 32V , поэтому они сделали включать оболочку Борна.

    (The 2BSD линия превратилась в параллельную развилку BSD для Digital в миникомпьютеров PDP , в то время как линии 3BSD и 4BSD продолжал воспользоваться новыми типами компьютеров , как VAXen и Unix рабочих станций 2.9BSD была по существу версия PDP из 4.1cBSD;. Они были современники, и общий код . ПРП не просто исчезает , когда VAX прибыл, так что 2BSD линия еще Shambling вместе .)

    Можно с уверенностью сказать, что оболочка Bourne была повсюду в мире Unix к 1983 году. Это хорошее приближение к «навсегда» в компьютерной индустрии. MS-DOS получил иерархическую файловую систему в том же год (Awww, как cuuute!) И первые 24-разрядные Macintosh с 9" B & W экрана - не оттенки серой, буквально черными и белыми - не вышло бы до начала следующего года.

  2. Оболочка Томпсона была довольно примитивной по сегодняшним меркам. Это была только интерактивная командная оболочка, а не среда программирования сценариев, которую мы ожидаем сегодня. У него действительно были такие вещи, как каналы и перенаправление ввода / вывода, которые мы считаем прототипической частью «оболочки Unix», так что мы думаем о командной оболочке MS-DOS как о получении их из Unix.

    Bourne оболочка также заменить ПРБ оболочку , которая добавила важные вещи оболочки Томпсона , как программируемость ( if, switchи while) и раннюю форму переменных окружения. Оболочка PWB еще менее запомнилась, чем оболочка Томпсона, поскольку она не была частью каждой версии Unix.

  3. Если кто-то не знает, что такое совместимость с оболочкой POSIX и Bourne, это может означать целый ряд вещей.

    С одной стороны, они могли бы использовать оболочку Bourne 1979 года в качестве базовой линии. « sh-Совместим сценарий» в этом смысле означает, что , как ожидается, прекрасно работать на истинной оболочке Bourne или любом из его наследников и клонов: ash, bash, ksh, zshи т.д.

    Кто-то в другом крайнем случае принимает оболочку, указанную POSIX, как базовую линию. Мы принимаем так много функций оболочки POSIX как «стандартные» в наши дни, что часто забываем, что их на самом деле не было в оболочке Bourne: встроенная арифметика, управление заданиями, история команд, псевдонимы, редактирование командной строки, $()форма команды замена и т. д.

  4. Хотя у оболочки Korn есть корни, восходящие к началу 1980-х, AT & T не выпускала ее в Unix до выпуска System V Release 4 в 1988 году. Поскольку так много коммерческих Unix- систем основано на SVR4, это включало kshпрактически все соответствующие коммерческие Unix из конец 1980-х годов.

    (Несколько странных разновидностей Unix, основанных на SVR3 и более ранних, сохранившихся на рынке после выхода SVR4, но они были первыми против стены, когда началась революция .)

    1988 год - это также год, когда вышел первый стандарт POSIX с его оболочкой Porn на основе оболочки Korn. Позже, в 1993 году, вышла улучшенная версия оболочки Korn. Поскольку POSIX эффективно прибил оригинал на месте, kshразделились на две основные версии: ksh88и ksh93, названные в честь лет, проведенных в их расколе.

    ksh88не является полностью POSIX-совместимым, хотя различия невелики, поэтому некоторые версии ksh88оболочки были исправлены как POSIX-совместимые. (Это из интересного интервью на Slashdot с доктором Дэвидом Г. Корном . Да, парень, который написал оболочку.)

    ksh93является полностью совместимым надмножеством оболочки POSIX . Разработка ksh93была спорадической с тех пор, как хранилище первоисточника перешло с AT & T на GitHub, причем последнему выпуску было около 3 лет, когда я пишу это, ksh93v. (Базовое имя проекта остается ksh93с добавленными суффиксами для обозначения версий выпуска после 1993 года.)

    Системы, которые включают оболочку Korn отдельно от оболочки POSIX, обычно делают ее доступной /bin/ksh, хотя иногда она скрывается в другом месте.

    Когда мы говорим об kshоболочке Korn по имени, мы говорим о ksh93функциях, которые отличают ее от ее обратно совместимых подмножеств оболочки Bourne и POSIX. Вы редко сталкиваетесь с чистым ksh88сегодня.

  5. AT & T сохраняла собственный исходный код оболочки Korn до марта 2000 года . К тому времени ассоциация Linux с GNU Bash была очень сильной. Bash и ksh93 каждый из них имеют преимущества перед другими , но на данный момент инерция тесно связывает Linux с Bash.

    Что касается того, почему ранние поставщики Linux чаще всего выбирают GNU Bash pdksh, который был доступен в то время, когда Linux начинал, я думаю, это потому, что большая часть остальной части пользовательского пространства также пришла от проекта GNU . Bash также несколько более продвинут, чем pdksh, поскольку разработчики Bash не ограничиваются копированием функций оболочки Korn.

    Работа над ним pdkshпрекратилась примерно в то время, когда AT & T выпустила исходный код для настоящей оболочки Korn. Однако есть две основные вилки, которые все еще поддерживаются: OpenBSD pdkshи MirBSD Korn Shellmksh .

    Интересно, что mkshэто единственная реализация оболочки Korn, в настоящее время упакованная для Cygwin.

  6. GNU Bash выходит за рамки POSIX во многих отношениях, но вы можете попросить его работать в более чистом режиме POSIX .

  7. csh/ tcshОбычно в начале 90-х годов в BSD Unixes была интерактивная оболочка по умолчанию.

    Будучи вариантом BSD , ранние версии Mac OS X были такими же, через Mac OS X 10.2 «Jaguar» . OS X переключил оболочку по умолчанию с tcshBash в OS X 10.3 «Пантера» . Это изменение не коснулось систем, обновленных с версии 10.2 или более ранних. Существующие пользователи в этих преобразованных системах сохранили свою tcshоболочку.

    FreeBSD утверждает, что по-прежнему использует tcshоболочку по умолчанию , но на виртуальной машине FreeBSD 10, которую я здесь имею, оболочкой по умолчанию является один из POSIX-совместимых вариантов оболочки Almquist . Это верно и для NetBSD.

    В OpenBSD pdkshвместо этого используется оболочка по умолчанию.

    Более высокая популярность Linux и OS X заставляет некоторых желать, чтобы FreeBSD также переключилась на Bash, но они не будут делать это в ближайшее время по философским причинам . Это легко переключить , если это вас беспокоит.

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

    Мне известен только один способ запустить подлинную винтажную оболочку Bourne 1979 года на современном компьютере: использовать образы дисков Ancient Unix V7 с симулятором SIMH PDP-11 из проекта Computer History Simulation Project . SIMH работает практически на каждом современном компьютере , а не только на Unix-подобных. SIMH работает даже на Android и iOS .

    С OpenSolaris , Sun с открытым кодом версии SVR4 оболочки Борна впервые. До этого исходный код для версий оболочки Bourne после V7 был доступен только тем, у кого есть лицензия на исходный код Unix.

    Этот код теперь доступен отдельно от остальной части несуществующего проекта OpenSolaris из нескольких разных источников.

    Наиболее прямым источником является проект оболочки Heirloom Bourne . Это стало доступно вскоре после оригинальной версии 2005 OpenSolaris. В течение следующих нескольких месяцев была проведена некоторая работа по переносимости и исправлению ошибок, но затем разработка проекта остановилась.

    Йорг Шиллинг проделал лучшую работу по поддержке версии этого кода, как и oshв его пакете инструментов Schily . См. Выше для получения дополнительной информации об этом.

    Помните, что эти оболочки, полученные из выпуска исходного кода 2005 года, содержат поддержку многобайтовых наборов символов , управление заданиями, функции оболочки и другие функции, отсутствующие в исходной оболочке Bourne 1979 года.

    Один из способов определить, используете ли вы оригинальную оболочку Bourne, - проверить, поддерживает ли она недокументированную функцию, добавленную для облегчения перехода от оболочки Thompson: ^в качестве псевдонима для |. То есть команда like ls ^ moreвыдаст ошибку в оболочке типа Korn или POSIX, но она будет вести себя как ls | moreв настоящей оболочке Bourne.

  9. Иногда вы столкнулись fish, scshили rc/esприверженец, но они еще реже , чем поклонники C оболочки.

    rcСемейство оболочек обычно не используется в системах Unix / Linux, но семья является исторически важным, что , как он получил место в диаграмме выше. rcявляется стандартной оболочкой Plan 9 от операционной системы Bell Labs , своего рода преемника 10-го издания Unix , созданного в рамках постоянных исследований Bell Labs по проектированию операционной системы. Он несовместим как с Bourne, так и с оболочкой C на уровне программирования; там, наверное, урок.

    Наиболее активным вариантом, по- rcвидимому, является поддерживаемый Тоби Гудвином , основанный на rcклоне Unix Байрона Ракициса.

Уоррен Янг
источник
Если вы хотите узнать больше отношений, например, с UNOS "команда", "bsh" и недавней Bourne Shell, пришлите мне записку. Подсказка: в команде UNOS была встроенная команда do, выполняющая роль однострочного сценария оболочки с аргументами. Эта идея была перенесена в оболочку Bourne как «дош» и допускает параметрируемые псевдонимы, чего вы не можете получить из ksh или bash.
Шил
Может быть стоит отметить, что сам pdksh основан на оболочке Forsyth. В основном это забыто сегодня, но оно имеет некоторое историческое значение в наследии pdksh, но также является оболочкой некоторых версий minix и было перенесено в msdos.
Стефан Шазелас
25

«sh совместимый» относится к POSIXsh , базовой оболочке, которая должна существовать во всех совместимых системах. Совместимый с sh скрипт должен работать на любом POSIX-совместимом компьютере.

Причина, по которой необходимо так сказать, заключается в том, что обычно /bin/shэто символическая ссылка /bin/bash, которая позволяет некоторым Bashisms вставлять в сценарии, которые объявляют себя для использования shс #!/bin/sh. Эти сценарии не работают в системах, которые не используют bashas /bin/sh, включая некоторые коммерческие Unices навсегда, а также Debian и его производные в последнее время.

В частности dash, в shпоследнее время появилась тенденция использовать оболочку Debian Almquish в качестве настройки по умолчанию , потому что она меньше и должна быть быстрее. Эта тенденция выдвинула на первый план много тех Bashisms, которые были в предполагаемых shсценариях. Описание что-то как «совместимый с sh» означает, что оно явно предназначено для работы с этими системами, оставаясь полностью в языке, указанном POSIX - все оболочки будут реализовывать расширенный набор этих функций, поэтому он гарантированно будет работать везде, но их расширения не совместимы друг с другом.

Различные оболочки имеют свою собственную историю разработки и со временем расходятся в разных направлениях, так как они добавили функции, помогающие интерактивному использованию для своих пользователей, или расширения сценариев, такие как ассоциативные массивы. «Sh-несовместимый» сценарий будет использовать некоторые из этих нестандартных расширений, например, [[условные выражения Bash .

Функции не-POSIX в bashи tcshи zshи во всех других текущих оболочках полезны , и есть множество случаев, когда вы можете захотеть или нуждаться в них. Их просто не следует использовать в сценарии, с которым нужно работать /bin/sh, потому что вы не можете полагаться на эти функции, находящиеся в базовой shреализации в системе, на которой вы работаете.

Скрипт, который должен использовать, скажем, ассоциативные массивы, должен обеспечивать его запуск bashвместо sh:

#!/bin/bash
declare -A array

Это будет работать где угодно bash. Скрипты, которые не нуждаются в расширенной функциональности и предназначены для переносимости, должны декларировать, что они используют, shи придерживаться языка команд базовой оболочки.

Майкл Гомер
источник