W większości skryptów powłoki, które widziałem (oprócz tych, których sam nie napisałem), zauważyłem, że shebang jest ustawiony na #!/bin/sh
. Tak naprawdę nie zaskakuje mnie to w przypadku starszych skryptów, ale dotyczy to również całkiem nowych skryptów.
Czy jest jakiś powód, by preferować coś /bin/sh
więcej /bin/bash
, skoro bash
na wielu maszynach z Linuksem i BSD jest to dość wszechobecny i często domyślny program sprzed dekady?
/bin/sh
jeśli nie korzystasz z określonychbash
funkcji. Pewnego dnia możesz użyć jednego ze skryptów w systemie, w którym nie jest on zainstalowany (serwer zdalny, komputer wbudowany ...)...the answers so far are fairly subjective...
„Subiektywne” stwierdzenie jest z definicji oparte na opiniach./bin/bash
powinien być używany tylko wtedy, gdy bash jest wyraźnie potrzebny. Przez ponad 40 lat jako programista, na długo przedtembash
, prawie nigdy nie potrzebowałem tego wyraźnie , z wyjątkiem testów. (Staram się również unikać rozszerzeń powłoki, ale większość moich skryptów jest przeznaczona do dystrybucji.) Wiele skryptów w sieci powinno być również przeznaczonych do szerokiego użytku.Odpowiedzi:
/bin
.źródło
/bin/sh
jest szybszy, jeśli nie jestbash
, wciąż istnieje kilka systemów, takich jak OS / X lub RHEL, gdzie/bin/sh
jestbash
./bin/sh
jest to całkiem sporo skryptów/bin/bash
. Przełączanie Ubuntu z bash na dash zepsuło wszystkie z nich.#!/bin/bash
gdyby chcieli Bash (nic złego z tym!). Zmiany dokonano głównie na wcześniejszym etapie w Debianie. Poprawił komfort użytkowania, miał wymierny wpływ na czas uruchamiania systemu. Wpłynęło to również pozytywnie na bezpieczeństwo, patrz „Shellshock”.Większość skryptów systemowych w (związanych z Debianem: Ubuntu, Mint itp.) Linux jest napisanych tak, aby działały w szybszym myślniku, który jest domyślnym / bin / sh w tych systemach. Powód jest dwojaki:
Szybkość systemu. Mniejszy kod myślnika ładuje się szybciej, a także działa szybciej. Z pewnym (małym?) Dodatkowym wysiłkiem (kosztem) dla programistów skryptów powłoki.
Bezpieczeństwo. Różnorodność powłok pomaga w odporności na błędy. Systemy Debian nie były w większości podatne na wstrząs, ponieważ domyślna powłoka nie miała takiej podatności.
Bash jest rzeczywiście domyślną powłoką dla użytkowników , ponieważ jest bardziej wydajny i zawiera znacznie więcej elementów, aby ułatwić kodowanie. Jest to również domyślny
sh
w Mac OS (ten, do którego prowadzi link z / bin / sh). Jednak wywołaniebash
z nazwą łączash
powoduje, że zaczyna się jako powłoka zgodna z posix.źródło
eval
, z towarzyszącym narażeniem bezpieczeństwa; podobnie, bez wbudowanej obsługi wyrażeń regularnych, może być konieczne użycie poleceń zewnętrznych (z dużym obciążeniem wydajnościowym) w celu dopasowania nawet w obrębie jednej linii itp.Inni zauważyli, że przesłanki pytania, że powłoka Bourne Again jest domyślna i wszechobecna, są całkowicie błędne.
Poza tym istnieją naprawdę dobre powody, aby używać do interpretacji skryptów powłoki czegoś innego niż powłoka Bourne Again. Przyczyny te zmotywowały duży projekt Ubuntu i Debiana, przez wiele lat, do usunięcia bashism i spowodowania, aby tyle skryptów powłoki było uruchamianych przez inicjalizację systemu (która była dużą ilością skryptów powłoki w Systemie 5
rc
), a instalacja / usuwanie pakietów korzystała z Powłoka Almianist Debiana zamiast powłoki Bourne Again.Mówiąc wprost: powłoka Bourne Again, pełna interaktywnych funkcji, nie jest najszybszym interpretatorem powłoki dla skryptu zgodnego z POSIX. Jeśli więc można stworzyć własne skrypty powłoki zgodne z POSIX, interpretując je za pomocą lżejszego programu, takiego jak powłoka Debian Almquist, system będzie działał lepiej. (Ostatecznie Debian musiał dokonać drobnych zmian w powłoce Almquist, aby dodać obsługę kilku konstrukcji powłok innych niż POSIX, które były po prostu zbyt głęboko i szeroko osadzone i zbyt przydatne, aby się ich pozbyć.)
Wynikiem tego wszystkiego był znaczny wzrost wydajności ładowania początkowego.
Istnieją tutaj dwie odrębne klasy powłok:
Zauważ, że mówienie o tym jako o „preferowaniu
/bin/sh
” jest nadmiernym uproszczeniem. Debian miał przynajmniej dwa cele:W obliczu administratorów używających powłoki Debian Almquist, powłoki Z (w trybie POSIX), powłoki Bourne Again (w trybie POSIX), powłoki MirBSD Korn i innych
/bin/sh
, ponieważ albo…… Czyniąc skrypty tak przenośnymi, jak to możliwe, aby przełączanie
/bin/sh
mapowanych elementów nie powodowało uszkodzenia ; lub… Tworzenie nieprzenośnych skryptów wyraźnie celuje we właściwy program interpretera , zamiast po prostu oczekiwać
/bin/sh
od niego mapy.Było czyniąc Almquist Debian powłoki domyślne odwzorowania dla
/bin/sh
zamiast Bourne Shell, tak że te skrypty, które były POSIX-conformant (lub, bardziej poprawnie, Debian Policy Instrukcja conformant) biegł szybciej.I oczywiście, kiedy się w to zagłębi, można pójść o wiele dalej; takich jak uznając kompromisów sprawność pokroju
/bin/true
i/usr/bin/clear
jest skrypty powłoki lub skompilowane programy. Na szczęście wykracza to poza zakres tej odpowiedzi. ☺Nic z tego nie jest oczywiście nowe, ani nawet specyficzne dla Uniksa. Jeszcze przed przełomem wieku napisałem i opublikowałem interpretera wiersza poleceń, który pojawiał się zarówno w wersji „interaktywnej”, jak i „nieinteraktywnej”, wyjaśniając ten podział w swoim doco i zwracając uwagę na różnicę między zmiennymi środowiskowymi
COMSPEC
aOS2_SHELL
zmiennymi. Podobnie dyskusja na temat usuwania baszizmów w Systemie V Debianarc
i skryptach instalacji / usuwania pakietów sięga lat 90.Dalsza lektura
/bin/sh
. Ubuntu wiki./bin/sh
. Debian Wiki.źródło
Schily Bourne Shell
stronie man, patrz schilytools.sourceforge.net/bosh.html są odpowiednie, aby umożliwić ludziom zrozumienie, jak napisać przenośny skrypt (to zależy tylkoBourne Shell features
od 1989 roku). To, co zrobiłem, to wspomnienie o każdym ulepszeniu, którego nie było w starych Skorupach Bourne'a. BTW: Interesuje mnie również lista baszizmów w desce rozdzielczej.Tak. Doskonała odpowiedź @ Marco przedstawia to dobrze.
Pisząc własne skrypty, powinieneś wskazać skrót na najbardziej ogólną rzecz, na której testowałeś.
W moim systemie (Centos 6.6)
sh
jest dowiązanie symboliczne dobash
:Oznacza to, że zawsze używam
#!/bin/bash
w shebang, chyba że potwierdzę, że nie mam bashimów w moim skrypcie.Ustawiając shebang
#!/bin/sh
, obiecujesz, że skrypt będzie działał ze wszystkimi implementacjamish
.Jest to znacznie większa obietnica niż stwierdzenie, że skrypt będzie działał z bash.
Oto przykład skryptu, który będzie działał niepoprawnie w zależności od
sh
implementacji używanej przez system:Podczas korzystania
bash
ze skryptu wydrukujemy:Podczas korzystania
dash
ze skryptu wydrukujemy:Jeśli chcę użyć
#!/bin/sh
tego, co muszę zrobić?checkbashisms
- Zauważ, że nie znajdzie to wszystkich bashimów. Nie znalazłem bashizmu w moim skrypcie powyżejsh
implementacji. Zazwyczajdash
testuję, ale spodziewam się, że niektóre bashizmy lub dashimy mogą się jeszcze przedostać.Strona DashAsBinSh na wiki Ubuntu zawiera wiele interesujących informacji.
źródło
/bin/sh
; tylko te zgodne z POSIX.Jedynym pozostałym powodem napisania skryptu powłoki zamiast skryptu w bardziej wydajnym i ergonomicznym języku jest to, że przenośność na starszych systemach z nieznanym zestawem zainstalowanego oprogramowania jest ważniejsza niż jakikolwiek inny czynnik .
/bin/sh
to jedyny interpreter skryptów dostępny we wszystkim, co nazywa się Unix. Ale na okropnej liczbie starszych systemów/bin/sh
i powiązane narzędzia nie są nawet zgodne ze specyfikacją POSIX.1-1996 dotyczącą „powłoki i narzędzi”, nie mówiąc już o czymś bardziej nowoczesnym. Narzędzia zgodne ze standardami to opcjonalny dodatek, zainstalowany w/usr/xpg4
takiej lub nieoczywistej lokalizacji. 1 Skrypty do języka powłoki z przenośnym podzbiorem są jeszcze bardziej uciążliwe i podatne na błędy niż skrypty do języka powłoki POSIX. (Przeczytajconfigure
kiedyś skrypt wygenerowany przez Autoconf, jeśli mi nie wierzysz. Wystarczy konfiguracja, aby cię przekonać).Ale jeśli możesz założyć, że jest zainstalowany jakikolwiek inny interpreter skryptów (np. Bash), możesz założyć interpreter dla lepszego języka skryptowego . Na przykład Perl jest bardziej dostępny niż Bash.
Dlatego nigdy nie powinieneś pisać
#! /bin/bash
skryptu, ponieważ jeśli jest to opcja, lepszym językiem jest również opcja.1 Na przykład Solaris 10 i starsze dostarczały oryginalną powłokę Bourne'a jako
/bin/sh
. Zostałem poinformowany, że Solaris 11 zaktualizował go do ksh93.źródło
/bin/sh
jest POSIX.1-1996, ale w rzeczywistości oryginalną powłoką Bourne'a o składni sprzed POSIX. To sprawia, że skrypt jest bardzo kiepski, jeśli chodzi o uruchamianie skryptów w tych wydaniach. Używałyby przenośne skrypty w systemie Solaris, które nie będą bardzo przenośne w innych systemach operacyjnych. W najnowszym Solarisie Oracle Solaris 11 po raz pierwszy wydany w 2011 r. Jest nowoczesnym urządzeniem, które jest zgodne z najnowszymi specyfikacjami POSIX i ma wiele nowoczesnych rozszerzeń.#!/bin/sh
#!/usr/xpg4/bin/sh
/bin/sh
ksh93
ash
które są dostarczane z busybox), i myślę, że zwolnienie ma rację, że perl jest częściej dostępny niż bash.bash
jest dostępny, to jest lepszy język, więc nigdy nie powinieneś pisać żadnegobash
kodu”. Ponadto, jak wskazuje @sixtyfootersdude, powinieneś zawsze używać,#!/bin/bash
chyba że sprawdziłeś, czy twój skrypt działa z dowolną powłoką POSIX.Powinieneś faktycznie użyć albo
lub
w ten sposób wywołujesz dowolną powłokę według sposobu instalacji w tym systemie.
Aby być bardzo bezpiecznym ( np. W przypadku restartów dla jednego użytkownika), używaj w
sh
inny sposóbbash
.źródło
the advantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH. The disadvantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH.
prawdopodobnie dotyczy to równieżsh
ibash
.#!/bin/env
niczego w przenośnym skrypcie. Całkowicie uzasadnione jest założenie, że/bin/sh
istnieje i jest działającą powłoką zgodną z POSIX. Z drugiej strony żaden z moich systemów nie ma/bin/env
./bin/sh
. POSIX nie wymaga tego i raczej definiuje inne reguły, aby uzyskać środowisko zgodne z POSIX na certyfikowanej platformie POSIX./usr/bin/env
nie jest powszechnie dostępny ...