Ви отримали це назад. /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/shMacOS / 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 (чергове повторне втілення оболонки Борна))