Ze strony Shell Command Language specyfikacji POSIX:
Jeśli pierwszy wiersz pliku poleceń powłoki zaczyna się od znaków „#!”, Wyniki nie są określone.
Dlaczego zachowanie #!
nieokreślone przez POSIX? Dziwi mnie, że coś tak przenośnego i powszechnie używanego miałoby nieokreślone zachowanie.
exec()
funkcję. Zatem sprawdzanie w wielu powłokach tak naprawdę nie mówi, jak przenośny jest.Odpowiedzi:
Myślę przede wszystkim dlatego, że:
zachowanie różni się znacznie między implementacją. Zobacz szczegóły na https://www.in-ulm.de/~mascheck/various/shebang/ .
Może jednak teraz określać minimalny podzbiór większości implementacji uniksopodobnych: jak
#! *[^ ]+( +[^ ]+)?\n
(tylko znaki z przenośnego zestawu znaków w nazwie pliku w tych jednym lub dwóch słowach), gdzie pierwsze słowo jest absolutną ścieżką do natywnego pliku wykonywalnego, rzecz nie jest za długi i zachowanie nieokreślone, jeśli plik wykonywalny jest setuid / setgid, a implementacja określa, czy ścieżka interpretera lub ścieżka skryptu jest przekazywanaargv[0]
do interpretera.POSIX i tak nie określa ścieżki plików wykonywalnych. Kilka systemów ma narzędzia sprzed POSIX w
/bin
//usr/bin
i mają narzędzia POSIX gdzie indziej (np. W Solarisie 10, gdzie/bin/sh
jest powłoka Bourne'a, a POSIX jest w niej/usr/xpg4/bin
; Solaris 11 zastąpił ją ksh93, który jest bardziej zgodny z POSIX, ale większość innych narzędzia/bin
nadal są starożytnymi, innymi niż POSIX). Niektóre systemy nie są systemami POSIX, ale mają tryb / emulację POSIX. Wszystko, czego wymaga POSIX, to istnienie udokumentowanego środowiska, w którym system zachowuje się POSIXly.Zobacz na przykład Windows + Cygwin. W rzeczywistości w Windows + Cygwin she-bang jest honorowana, gdy skrypt jest wywoływany przez aplikację cygwin, ale nie przez natywną aplikację Windows.
Więc nawet jeśli POSIX określił mechanizm shebang, nie można go użyć do pisania skryptów POSIX
sh
/sed
/awk
... (należy również pamiętać, że mechanizm shebang nie może być użyty do napisania niezawodnegosed
/awk
skryptu, ponieważ nie pozwala na przekazanie końca opcji znacznik).Fakt, że jest nieokreślony, nie oznacza, że nie możesz go użyć (cóż, mówi, że nie powinieneś zaczynać od pierwszego wiersza,
#!
jeśli spodziewasz się, że będzie to tylko zwykły komentarz, a nie she-bang), ale POSIX nie daje żadnej gwarancji, jeśli to zrobisz.Z mojego doświadczenia wynika, że używanie shebangs daje większą gwarancję przenośności niż używanie sposobu pisania skryptów powłoki przez POSIX: zrezygnuj z she-bang, napisz skrypt w
sh
składni POSIX i miej nadzieję, że cokolwiek wywołuje skrypt wywołuje zgodnysh
z nim POSIX , który jest dobrze, jeśli wiesz, że skrypt zostanie wywołany w odpowiednim środowisku przez odpowiednie narzędzie, ale nie inaczej.Być może będziesz musiał zrobić takie rzeczy jak:
Jeśli chcesz być przenośny na Windows + Cygwin, być może będziesz musiał nazwać swój plik rozszerzeniem
.bat
lub.ps1
i użyć podobnej sztuczki dlacmd.exe
lubpowershell.exe
wywołać cygwinsh
na tym samym pliku.źródło
sh
nie potrzebowałby linii hashbang, ponieważ byłby wykonywany przez POSIXsh
.execlp
lubexecvp
były wykorzystywane, prawda? Gdybym miał użyćexecve
, spowodowałoby to ENOEXEC?Nie patrzysz wystarczająco głęboko.
W latach 80. mechanizm ten nie był de facto znormalizowany. Chociaż Dennis Ritchie go wdrożył, wdrożenie to nie dotarło do opinii publicznej po stronie AT&T wszechświata. Był efektywnie tylko publicznie dostępny i znany w BSD; z wykonywalnymi skryptami powłoki niedostępnymi w systemie AT&T Unix. W związku z tym standaryzacja nie była rozsądna. Stan rzeczy jest ilustrowany tym współczesnym doco, jednym z wielu takich:
- Stephen Frede (1988). „Programowanie w systemie X wydanie Y”. Biuletyn Grupy Użytkowników Australian Unix Systems . Tom 9. Liczba 4. p. 111.Ważnym punktem jest to, że patrzysz na powłoki, podczas gdy istnienie wykonywalnych skryptów powłoki jest w rzeczywistości kwestią
exec…()
funkcji. To, co robią powłoki, obejmuje prekursory wykonywalnego mechanizmu skryptowego, który do dziś można znaleźć w niektórych powłokach (a także obecnie jest obowiązkowy dlaexec…p()
podzbioru funkcji) i jest nieco mylący. W tym względzie normą należy się zająć to, jakexec…()
działa interpretowany skrypt, a w momencie, gdy POSIX był pierwotnie tworzony , po prostu nie działał przede wszystkim w znacznej części spektrum docelowych systemów operacyjnych .Podporządkowane pytanie, dlaczego nie zostało to ujednolicone ponieważ, zwłaszcza jako mechanizm magiczna liczba dla tłumaczy skryptów nie osiągnął publicznej wiadomości w stronę AT & T wszechświata i zostało udokumentowane
-exec…()
w definicji systemu 5 interfejsu , na przełomie 1990 :exec
. System V Interfejs Definicja . Tom 1. 1991.Niestety, zachowanie jest dziś prawie tak bardzo rozbieżne jak w latach 80. i nie ma naprawdę powszechnego zachowania, które można by znormalizować. Niektóre Unices (na przykład HP-UX i FreeBSD) nie obsługują skryptów jako interpretatorów skryptów. To, czy pierwszy wiersz to jeden, dwa lub wiele elementów oddzielonych spacjami, różni się w MacOS (i wersjach FreeBSD przed 2005) i innych. Maksymalna obsługiwana długość ścieżki jest różna.
␀
znaki spoza zestawu znaków przenośnej nazwy pliku POSIX są trudne, podobnie jak początkowe i końcowe białe znaki. To, co kończy się argumentem 0, 1 i 2, jest również trudne, ze znacznymi różnicami w zależności od systemu. Niektóre obecnie zgodne z POSIX, ale nie- Systemy Unix nadal nie obsługują żadnego takiego mechanizmu, a nałożenie na niego mandatu spowodowałoby, że przestałyby być zgodne z POSIX.Dalsza lektura
script
. NetBSD Różne informacje Podręcznik . 2005-05-06.źródło
Jak zauważono w niektórych innych odpowiedziach, implementacje są różne. Utrudnia to standaryzację i zachowanie kompatybilności wstecznej z istniejącymi skryptami. Dotyczy to nawet nowoczesnych systemów POSIX. Na przykład Linux nie w pełni tokenizuje linię shebang spacjami. macOS nie pozwala interpreterowi skryptów być innym skryptem.
Zobacz także http://en.wikipedia.org/wiki/Shebang_(Unix)#Portability
źródło