Masz to zacofane. /bin/shw 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/shpowłokę Korn lub powłokę zgodną z tą specyfikacją. W przypadku BSD stopniowo zmieniali /bin/shpoczą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, yashi niektóre pdkshpochodne włączenia trybu do POSIX przy wywołaniu jak shi 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 shskł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 shinterpretera 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/shshe-bang, głównym problemem byłyby systemy, w których /bin/shjest 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/shnie bashjest domyślnie. Obecnie jest dashto 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 bashi dashza /bin/shpomocą 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)).shzshshboshksh93yashlocal
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ą /binkatalogu, ale prawdopodobnie nie przejmujesz się tym), i na ogół jest to shinterpreter POSIX (aw rzadkich przypadkach (niestandardowa) powłoka Bourne'a ).
Ale shjest 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 bashani żadna z tych innych powłok nie zostanie zainstalowana w /bininnym miejscu (zwykle znajduje się /usr/local/binna BSD, gdy jest instalowana). I oczywiście nie ma gwarancji wersji powłoki, która zostanie zainstalowana.
Zauważ, że #! /path/to/executablenie 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-argjądro kończy się wykonaniem /some/filez some-optional-arg, ścieżki skryptu i oryginalnych argumentów jako argumenty. Możesz zrobić ten pierwszy wiersz, #! /bin/echo testaby 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, shinterpretuje kod zawartości zapisany w nim myscripti ignoruje ten pierwszy wiersz jako komentarz (zaczyna się od #).
¹ Prawdopodobnie jedynym obecnie systemem, w którym ktokolwiek z nas natknie się na system /bin/shoparty 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ą ( shję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 shgdzie indziej (w /usr/xpg4/bin/sh, na podstawie ksh88), ale zmieniło się to w Solarisie 11, gdzie /bin/shjest 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/shzshbashzshshshsourceshzsh
³ 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, boshale nie wiem, czy jest ona używana w żadnym systemie. Dzięki ksh88temu 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ć mkshlub jego większej lkshinkarnacji POSIX . To jest powłoka MirOS (wcześniej MirBSD) oparta na pdksh, sama oparta na powłoce Forsyth (kolejna reimplementacja powłoki Bourne))