Masz to zacofane. /bin/sh
w dzisiejszych czasach prawie nigdy nie jest powłoką Bourne'a i właśnie wtedy masz problem z używaniem She #! /bin/sh
-Bang.
Powłoka Bourne'a była powłoką napisaną pod koniec lat 70. i zastąpiła poprzednią powłokę Thompson (zwaną także sh
). Na początku lat 80. David Korn napisał kilka rozszerzeń dla powłoki Bourne'a, naprawił kilka błędów i powodował problemy z projektowaniem (i wprowadził kilka) i nazwał ją skorupą Korna.
Na początku lat 90. POSIX określił sh
język w oparciu o podzbiór powłoki Korn, a większość systemów obecnie zmieniła swój język na /bin/sh
powłokę Korn lub powłokę zgodną z tą specyfikacją. W przypadku BSD stopniowo zmieniali /bin/sh
początkowo (po tym, jak nie mogli już używać powłoki Bourne'a ze względów licencyjnych) powłokę Almquist, klon powłoki Bourne'a z niektórymi rozszerzeniami ksh, więc stała się zgodna z POSIX.
Obecnie wszystkie systemy POSIX mają powłokę o nazwie sh
(najczęściej, ale niekoniecznie w /bin
, POSIX nie określa ścieżki określonych przez nią narzędzi), która jest w większości zgodna z POSIX. Zasadniczo jest oparty na ksh88, ksh93, pdksh, bash, ash lub zsh², ale nie na powłoce Bourne'a, ponieważ powłoka Bourne'a nigdy nie była zgodna z POSIX3. Niektóre z tych skorup ( bash
, zsh
, yash
i niektóre pdksh
pochodne włączenia trybu do POSIX przy wywołaniu jak sh
i są mniej zgodne inaczej).
bash
(odpowiedź GNU na powłokę Korna) jest w rzeczywistości jedyną powłoką typu open source (i można powiedzieć, że obecnie jest utrzymywana, ponieważ inne są generalnie oparte na ksh88, który nie otrzymał żadnej nowej funkcji od lat 90.), który został certyfikowany jako zgodność z POSIX sh
(jako część certyfikacji macOS).
Kiedy piszesz skrypt za pomocą #! /bin/sh -
she-bang, powinieneś użyć standardowej sh
składni (i powinieneś również użyć standardowej składni narzędzi używanych w tym skrypcie, jeśli chcesz być przenośny, to nie tylko powłoka jest zaangażowana podczas interpretacji powłoki skrypt), to nie ma znaczenia, jaka implementacja tego standardowego sh
interpretera składni jest używana ( ksh
, bash
...).
Nie ma znaczenia, że te powłoki mają rozszerzenia ponad standard, o ile ich nie używasz. To tak, jakby pisać kod C, o ile piszesz standardowy kod C i nie używasz rozszerzeń jednego kompilatora (podobnego gcc
) lub drugiego, kod powinien kompilować się OK bez względu na implementację kompilatora, pod warunkiem, że kompilator jest zgodny.
Tutaj z #! /bin/sh
she-bang, głównym problemem byłyby systemy, w których /bin/sh
jest Bourne shell, że na przykład nie obsługuje standardowe funkcje, takie jak $((1+1))
, $(cmd)
, ${var#pattern}
... W takim przypadku konieczne może być obejścia takich jak:
#! /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
Nawiasem mówiąc, Ubuntu /bin/sh
nie bash
jest domyślnie. Obecnie jest dash
to powłoka oparta na NetBSD sh
, sama oparta na powłoce Almquist, która jest w większości zgodna z POSIX, z wyjątkiem tego, że nie obsługuje znaków wielobajtowych. W Ubuntu i innych systemach opartych na Debianie możesz wybierać pomiędzy bash
i dash
za /bin/sh
pomocą 4dpkg-reconfigure dash
) . skrypty dostarczane z Debianem powinny działać tak samo w obu powłokach, ponieważ są zapisane w standardzie polityki Debiana (nadzbiór standardu POSIX). Prawdopodobnie znajdziesz również pracować OK „s emulacji lub (prawdopodobnie nie , ani które nie mają polecenie wbudowane (wymagane przez politykę Debiana ale nie POSIX)).sh
zsh
sh
bosh
ksh93
yash
local
Wszystkie systemy w unix.stackexchange.com mają sh
gdzieś POSIX . Większość z nich ma /bin/sh
(możesz znaleźć bardzo rzadkie, które nie mają /bin
katalogu, ale prawdopodobnie nie przejmujesz się tym), i na ogół jest to sh
interpreter POSIX (aw rzadkich przypadkach (niestandardowa) powłoka Bourne'a ).
Ale sh
jest to jedyny plik wykonywalny interpretera powłoki, który z pewnością znajdziesz w systemie. W przypadku innych powłok możesz być pewien, że będą miały macOS, Cygwin i większość dystrybucji GNU / Linux bash
. Systemy operacyjne wywodzące się z SYSV (Solaris, AIX ...) zazwyczaj mają ksh88, prawdopodobnie ksh93. OpenBSD, MirOS będzie miał pochodną pdksh. macOS będzie miał zsh
. Ale z tego nie będzie żadnej gwarancji. Nie ma gwarancji, że bash
ani żadna z tych innych powłok nie zostanie zainstalowana w /bin
innym miejscu (zwykle znajduje się /usr/local/bin
na BSD, gdy jest instalowana). I oczywiście nie ma gwarancji wersji powłoki, która zostanie zainstalowana.
Zauważ, że #! /path/to/executable
nie jest to konwencja , jest to cecha wszystkich jąder uniksopodobnych ( wprowadzonych na początku lat 80. przez Dennisa Ritchiego ), która umożliwia wykonywanie dowolnych plików poprzez określenie ścieżki interpretera w pierwszym wierszu, zaczynając od #!
. Może to być dowolny plik wykonywalny.
Po uruchomieniu pliku, którego pierwsza linia rozpoczyna się #! /some/file some-optional-arg
jądro kończy się wykonaniem /some/file
z some-optional-arg
, ścieżki skryptu i oryginalnych argumentów jako argumenty. Możesz zrobić ten pierwszy wiersz, #! /bin/echo test
aby zobaczyć, co się dzieje:
$ ./myscript foo
test ./myscript foo
Kiedy używasz /bin/sh -
zamiast /bin/echo test
, jądro wykonuje /bin/sh - ./myscript foo
, sh
interpretuje kod zawartości zapisany w nim myscript
i ignoruje ten pierwszy wiersz jako komentarz (zaczyna się od #
).
¹ Prawdopodobnie jedynym obecnie systemem, w którym ktokolwiek z nas natknie się na system /bin/sh
oparty na powłoce Bourne'a, jest Solaris 10. Solaris jest jednym z niewielu uników, które zdecydowały się zachować tam powłokę Bourne'a ze względu na kompatybilność wsteczną ( sh
język POSIX nie jest w pełni wstecznie kompatybilny z powłoką Bourne'a) i (przynajmniej dla wdrożeń na komputery stacjonarne i pełne serwery) mają POSIX sh
gdzie indziej (w /usr/xpg4/bin/sh
, na podstawie ksh88), ale zmieniło się to w Solarisie 11, gdzie /bin/sh
jest teraz ksh93. Pozostałe są w większości nieczynne.
² MacOS / X stosowany się , a później zmieniła się . Używanie go jako implementacji POSIX nie jest głównym celem . Jego trybem jest przede wszystkim możliwość osadzania lub wywoływania ( ) kodu POSIX w skryptach/bin/sh
zsh
bash
zsh
sh
sh
source
sh
zsh
³ Ostatnio @schily rozszerzył powłokę OpenSolaris (bazującą na powłoce SVR4, opartą na powłoce Bourne'a), aby stała się zgodna z POSIX, bosh
ale nie wiem, czy jest ona używana w żadnym systemie. Dzięki ksh88
temu jest to druga powłoka zgodna z POSIX, oparta na kodzie powłoki Bourne'a
4 W starszych wersjach można również użyć mksh
lub jego większej lksh
inkarnacji POSIX . To jest powłoka MirOS (wcześniej MirBSD) oparta na pdksh, sama oparta na powłoce Forsyth (kolejna reimplementacja powłoki Bourne))