Jaka jest różnica między bash i sh?

28

Widzę dwa rodzaje używanych kodów:

#!/usr/bin/sh

i:

#!/user/bin/bash

Szukałem tego online, a opinie bardzo się różnią. Wyjaśnienia, które widziałem na większości stron internetowych, mówią tak sh jest starszy niż bashi że nie ma realnej różnicy.

Czy ktoś zna różnicę między nimi? Czy możesz dać mi praktyczny przykład, kiedy używać jednego nad drugim?

Saif Bechan
źródło
ogólny przegląd różnych skorup (nie tylko sh i bash ): http://en.wikipedia.org/wiki/Comparison_of_command_shells
akira
1
Kolejna wspaniała historia tutaj: faqs.org/faqs/unix-faq/shell/shell-differences
John Wright

Odpowiedzi:

34

bash jest nadzbiorem sh to znaczy. wszystko, co możesz zrobić sh możesz to zrobić bash.

Bash ma więcej funkcji (rozgałęzianie, wbudowane, tablice) ułatwiając pisanie skryptu. Kilka późniejszych * nix'ów /bin/sh jako link do /bin/bash

Pełne wyjaśnienie co oto tutorial

Nifle
źródło
5
@Saif Bechan: Jeden powód, dla którego powłoka Bourne'a ( sh ) nie został przedłużony, ponieważ Bash` został napisany przez kogoś innego. Założę się też, że były problemy z licencją. Przeczytaj artykuł o muszli Bourne'a en.wikipedia.org/wiki/Bourne_shell
Felix
7
Usuwanie sh złamie wiele skryptów, które oczekują, że będzie tam i polegać na sposobie analizowania rzeczy. Użytkownicy Linuksa mogą się tym nie przejmować, ale ludzie wydający tysiące dolarów na Solaris, AIX lub HP-UX mogą być bardzo zirytowani.
njd
3
... i dla jeszcze większej zabawy, dowiązania symboliczne / bin / sh Ubuntu. Dash nie jest całkowicie zgodny z sh lub bash, ale powinien działać szybciej. Kiedy system się uruchamia, wszystkie skrypty init.d działają i myślę, że ogólnie zaoszczędzony czas jest tego wart.
kbyrd
8
Jestem pewien, że Dash jest całkowicie zgodny. Problem polega na tym, że niektórzy ludzie piszą skrypty, które mówią / bin / sh, ale sam skrypt wymaga / bin / bash do działania. Nikt nie zauważa problemu, ponieważ przez większość czasu / bin / sh po prostu wskazuje na / bin / bash.
davr
8
@Saif: Jest jeszcze jeden powód sh nie został po prostu rozszerzony: jego kod źródłowy to czyste piekło. Spójrz. Jego domniemany być C ...
grawity
6

Tradycyjnie, / bin / sh byłaby oryginalną powłoką Bourne'a, która nie ma historii ani edycji wiersza poleceń, ani żadnej kontroli zadań.

Przez mniej więcej 15 lat większość Unixów miała zainstalowaną powłokę POSIX lub przynajmniej ksh lub bash (które są prawie podobne do POSIX), ale wciąż mają bardziej ograniczoną powłokę w / bin / sh

Powodem tego jest to, że starsze skrypty powłoki, które oczekują starszych sh polecenie nadal działa.
Ponieważ postacie lubią {, } i ! mają specjalne znaczenie dla basha, możliwe, że starszy skrypt powłoki używający tych znaków (bez ich ucieczki) może zawieść.
(Powłoka Bourne'a zajmie !!{1,2} dosłownie, podczas gdy bash interpretowałby to jako powtórzenie poprzedniego polecenia ( !! ) a następnie rozszerzenie nawiasów klamrowych).

Jednak w Linuksie sh polecenie jest prawie zawsze tylko linkiem do bash, ze wszystkimi tymi samymi funkcjami.

njd
źródło
2
Bash powinien (ale nie zawsze) zachowywać się w trybie zgodności sh, jeśli zostanie wywołany jako / bin / sh. Wiele rzeczy pękło, gdy Ubuntu przełączył / bin / sh z linkowania do / bin / bash na linkowanie do / bin / dash. Rzeczy, które załamały się, zakładały bashizmy, kiedy powinny używać standardowego sh.
Broam
4

sh może oznaczać powłokę Bourne'a lub / bin / sh, która jest inną powłoką (zgodną z POSIX) na większości nowoczesnych platform. „Powłoka POSIX” to streszczenie powłoka zdefiniowana przez POSIX , który jest implementowany przez bash w trybie POSIX lub domyślnie ksh lub dash. / bin / sh jest czasami nazywany także powłoką POSIX, ponieważ jest to powłoka zgodna z POSIX na większości platform. Oryginalne powłoki Bourne'a nie są powłokami POSIX.

bashref ma listę różnice między powłokami bash i Bourne . man bash ma listę zmienia się, gdy bash jest wywoływany w trybie POSIX .

/ bin / sh nie jest dowiązaniem symbolicznym ani twardym dowiązaniem w systemie OS X, ale ma prawie taki sam rozmiar jak / bin / bash:

$ ls -li /bin/{ba,}sh
29631757 -r-xr-xr-x  1 root  wheel  1333920 Jul 26 01:52 /bin/bash
29631758 -r-xr-xr-x  1 root  wheel  1334000 Jul 26 01:52 /bin/sh

człowiek bash :

Jeśli bash jest wywoływany z nazwą sh, próbuje jak najdokładniej naśladować zachowanie uruchamiania wersji historycznych sh, dostosowując się również do standardu POSIX.

Naśladowanie powłok Bourne'a jest poza tym dość ograniczone. bash +B (Bourne) faktycznie wyłączy funkcje takie jak rozwijanie nawiasów.

$ sh
$ echo {a,b}
a b
$ echo $BASH_VERSION
3.2.48(1)-release
$ bash +B
$ echo {a,b}
{a,b}

Ale nawet jeśli wyłączysz tryb POSIX, echo zachowuje się jak echo -e domyślnie:

$ sh
$ shopt -uo posix
$ echo '1\b2'
2

/ bin / sh jest kreską Ubuntu , więc trochę bashisms pracuj z / bin / sh na OS X, ale nie na Ubuntu.

Jeśli rzeczywiście chcesz pisać skrypty do (czegoś) oryginalnych powłok Bourne'a, możesz użyć #!/usr/bin/env bash +B zamiast.

Myślę, że pisanie skryptów dla basha jest łatwiejsze niż unikanie funkcji, które nie są częścią specyfikacji POSIX lub powłok Bourne'a lub testowanie wszystkiego z innymi powłokami.

Lri
źródło
2

Właściwie, nawet jeśli / bin / sh może być linkiem do / bin / bash, jeśli jest uruchamiany, to zachowuje się inaczej. Z podręcznika bash:

Jeśli bash jest wywoływany z nazwą sh, próbuje naśladować zachowanie uruchamiania      historyczne wersje sh tak ściśle, jak to możliwe, przy jednoczesnym dostosowaniu do POSIX      standard również.

Tak jak sh, próbuje emulować historyczne zachowanie sh. Tak jak bash, próbuje być jak najbardziej użyteczny jako interaktywna powłoka logowania.

KeithB
źródło
2

W wielu systemach, aw szczególności w Solarisie, bash jest dynamicznie połączony, podczas gdy sh jest statycznie połączony. Może to stanowić zagrożenie bezpieczeństwa, dlatego użytkownik root powinien używać tylko / bin / sh jako powłoki (jeśli kiedykolwiek będziesz musiał zalogować się jako root).

alev
źródło
2
Również może być przydatny w nagłych wypadkach, jeśli zrobiłeś coś złego ldconfig lub Twój /lib katalog zostanie z jakiegoś powodu wymazany.
LawrenceC