Ви отримали це назад. /bin/sh
майже ніколи не буває оболонкою Борна в наші дні, і саме тоді у вас виникають проблеми, коли ви використовуєте She #! /bin/sh
-bang.
Оболонка Борна була оболонкою, написаною наприкінці 70-х років і замінила попередню оболонку Томпсона (також її називали sh
). На початку 80-х Девід Корн написав кілька розширень для оболонки Борна, виправив декілька помилок та незручності дизайну (і представив деяких) і назвав його оболонкою Корна.
На початку 90-х POSIX вказав sh
мову, засновану на підмножині оболонки Korn, і більшість систем тепер змінили їх /bin/sh
на або оболонку Korn, або на оболонку, відповідну цій специфікації. Що стосується BSD, вони поступово змінювали свої /bin/sh
, спочатку (після того, як вони більше не могли використовувати оболонку Bourne з ліцензійних причин) оболонку Almquist, клон оболонки Bourne з деякими розширеннями ksh, тому вона стала сумісною з POSIX.
Сьогодні всі POSIX-системи мають оболонку, яку називають sh
(найчастіше, але не обов'язково в /bin
, POSIX не визначає шлях утиліт, які вона вказує), які, як правило, сумісні з POSIX. Він, як правило, заснований на ksh88, ksh93, pdksh, bash, ash або zsh², але не оболонці Bourne, оскільки оболонка Bourne ніколи не відповідала POSIX³. Деякі з цих оболонок ( bash
, zsh
, yash
і деякі pdksh
похідні включити режим POSIX-сумісний при виклику , як sh
і в меншій мірі відповідає іншим чином ).
bash
(відповідь GNU на оболонку Korn) насправді є єдиною оболонкою з відкритим кодом (і можна сказати, що підтримується лише зараз, оскільки інші, як правило, базуються на ksh88, який не отримав жодної нової функції з 90-х років), сертифікований як будучи сумісним з POSIX sh
(як частина сертифікації macOS).
Коли ви пишете скрипт із #! /bin/sh -
she-bang, ви повинні використовувати стандартний sh
синтаксис (а також використовувати стандартний синтаксис для утиліт, що використовуються в цьому сценарії, якщо ви хочете бути портативними, це не тільки оболонка, яка бере участь при інтерпретації оболонки скрипт), то не має значення, яка реалізація цього стандартного 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
' ( 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/bin
на BSD, коли він встановлений, наприклад). І звичайно ніякої гарантії версії оболонки, яка буде встановлена.
Зауважте, що #! /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
, заснованою на оболонці Борна, - Solaris 10. Solaris - один з небагатьох Unice, який вирішив зберегти оболонку Bourne для зворотної сумісності ( sh
мова POSIX не повністю) назад сумісні з оболонкою Bourne і (принаймні для настільних і повних розгортань сервера) є POSIX в sh
інших місцях (в /usr/xpg4/bin/sh
, заснованих на ksh88), але це змінилося в Solaris 11, де /bin/sh
зараз ksh93. Інші здебільшого є неіснуючими.
² Раніше /bin/sh
MacOS / X бувzsh
, але згодом був змінений на bash
. Це не zsh
основний фокус, який слід використовувати як sh
реалізацію POSIX . Його sh
режим полягає в першу чергу, щоб мати можливість вбудовувати або викликати ( source
) sh
код POSIX у zsh
сценарії
³ Нещодавно @schily розширив оболонку OpenSolaris (база на оболонці SVR4, заснована на оболонці Bourne), щоб стати сумісним POSIX, bosh
але я не знаю, що він ще використовується в будь-якій системі. Поряд з ksh88
цим робить його другою сумісною з POSIX оболонкою на основі коду оболонки Bourne
4 У старих версіях ви також можете використовувати mksh
або більше lksh
втілення POSIX . Це оболонка MirOS (раніше MirBSD) на основі pdksh, сама заснована на оболонці Forsyth (чергове повторне втілення оболонки Борна))