Qual è la differenza tra #! / Bin / sh e #! / Bin / bash?


281

se scrivo,

#!/bin/bash
echo "foo"

o

#!/bin/sh
echo "foo"

entrambi danno lo stesso. Ho visto alcuni script che iniziano con #!/bin/sho #!/bin/bash. C'è qualche differenza tra loro?

Risposte:


242

bashe shsono due diverse conchiglie. Fondamentalmente bashè sh, con più funzionalità e una migliore sintassi. La maggior parte dei comandi funziona allo stesso modo, ma sono diversi.

Detto questo, dovresti realizzare che /bin/shsulla maggior parte dei sistemi sarà un collegamento simbolico e non invocherai sh. In Ubuntu si /bin/shcollegava a bash, comportamento tipico nelle distribuzioni Linux, ma ora è cambiato in un altro shell chiamato dash . Vorrei usare bash, poiché questo è praticamente lo standard (o almeno il più comune, dalla mia esperienza). In effetti, sorgono problemi quando uno script bash utilizzerà #!/bin/shperché lo script-maker presume che il collegamento sia bashquando non è necessario.

Per maggiori informazioni, http://man.cx/sh , http://man.cx/bash .


25
Il tuo primo paragrafo è abbastanza fuorviante. "sh" non è affatto una shell, ma un collegamento simbolico alla shell di sistema attualmente configurata , che sui sistemi Linux di solito è bash o dash (versioni recenti di Ubuntu che utilizzano quest'ultima).
thomasrutter,

19
/bin/shera una shell chiamata bourne shell nel 1977. bash è una shell compatibile / bin / sh che può essere usata come una sostituzione della shell bourne che è conforme posix. en.wikipedia.org/wiki/Bourne_shell
Alex,

5
bash è uno standard di fatto (molto usato) ma non è "standard"; Ub su Ubuntu usa dash , che è una shell conforme a Posix, quindi è davvero standard. Il mio consiglio è di usare il trattino il più spesso possibile per gli script, specialmente per gli script lato server. Sebbene bash sia più espressivo, dash funziona molto più velocemente ed è più sicuro.
Rick-777,

@ Rick-777 Quindi dovrei mettere esplicitamente #! / Bin / dash in cima ai miei script? Ho anche scritto script in cui scrivo solo comandi ed eseguo con ./scriptName e che ha funzionato bene. #! / Bin / yourShellHere è necessario?
user137717

@ Rick-777 Nei casi in cui escludo qualsiasi #! / Bin / shellName, ho denominato i file fileName.sh. Si collegherà implicitamente alla shell di sistema preferita senza dichiarare #! / Bin / sh?
user137717

82

Su Linux e altri sistemi simili a Unix puoi scegliere tra più shell.

La shell è responsabile non solo di disegnare il tuo piccolo prompt, ma di interpretare i tuoi comandi, specialmente se inserisci una logica complicata come pipe, condizionali e così via.

bash è la shell più comune utilizzata come shell predefinita per gli utenti dei sistemi Linux. È un discendente spirituale di altre conchiglie utilizzate nella storia di Unix. Il suo nome, bash è un'abbreviazione di Bourne-Again Shell, un omaggio alla shell Bourne che è stata progettata per sostituire, sebbene includa anche funzionalità della C Shell e della Korn Shell.

Viene eseguito, in questi giorni, da /bin/bash: qualsiasi sistema con bash lo renderà accessibile qui.

Tuttavia, non sono solo gli utenti che usano le shell. Gli script ( script di shell ) necessitano di shell per interpretarli. Quando si esegue uno script di shell, il sistema deve avviare un processo di shell per eseguire lo script.

Il problema è che diverse shell presentano minuscole incoerenze tra loro e quando si tratta di eseguire script, questi possono essere un vero problema. bash ha molte funzionalità di scripting che sono uniche solo per bash e non per altre shell. Questo va bene, se hai sempre intenzione di usare bash per eseguire quegli script. Altre shell possono tentare di emulare bash o aderire allo standard POSIX, che bash supporta abbastanza bene (anche se aggiunge le proprie estensioni a).

È possibile specificare nella parte superiore di uno script di shell con quale shell dovrebbe essere eseguita usando uno shebang. Uno script può specificare #!/bin/bashsulla prima riga, il che significa che lo script dovrebbe sempre essere eseguito con bash, piuttosto che con un'altra shell.

/ bin / sh è un eseguibile che rappresenta la shell di sistema . In realtà, di solito è implementato come un collegamento simbolico che punta all'eseguibile per qualunque shell sia la shell di sistema. La shell di sistema è il tipo di shell predefinita che gli script di sistema dovrebbero usare. Nelle distribuzioni Linux, per lungo tempo questo era solitamente un collegamento simbolico a bash , tanto che è diventato in qualche modo una convenzione collegare sempre / bin / sh a bash o una shell compatibile con bash. Tuttavia, negli ultimi due anni Debian (e Ubuntu) hanno deciso di cambiare la shell di sistema da bash a dash- una shell simile - rompendo con una lunga tradizione in Linux (beh, GNU) di usare bash per / bin / sh. Dash è visto come una shell più leggera e molto più veloce, che può essere utile per la velocità di avvio (e altre cose che richiedono molti script di shell, come gli script di installazione dei pacchetti).

Dash è abbastanza ben compatibile con bash, essendo basato sullo stesso standard POSIX. Tuttavia, non implementa le estensioni specifiche di bash. Esistono script che usano #!/bin/sh(la shell di sistema) come loro shebang, ma che richiedono estensioni specifiche di bash. Questo è attualmente considerato un bug che dovrebbe essere corretto da Debian e Ubuntu, che richiedono / bin / sh per poter funzionare quando puntato al trattino.

Anche se la shell di sistema di Ubuntu punta al trattino, la shell di accesso come utente continua a essere pazza in questo momento. Cioè, quando si accede a un emulatore di terminale ovunque in Linux, la shell di accesso sarà bash. La velocità di funzionamento non è tanto un problema quando la shell viene utilizzata in modo interattivo e gli utenti hanno familiarità con bash (e possono avere personalizzazioni specifiche di bash nella loro directory home).

Cosa dovresti usare quando scrivi gli script

Se lo script richiede funzioni supportate solo da bash, l'uso #!/bin/bash.

Ma se possibile, sarebbe bene assicurarsi che lo script sia compatibile con POSIX e utilizzare #!/bin/sh, che dovrebbe sempre, in modo abbastanza affidabile, puntare alla shell di sistema compatibile POSIX preferita in qualsiasi installazione.


18

Oltre alle risposte precedenti, anche se /bin/shè un collegamento simbolico a /bin/bash, #!/bin/shnon è del tutto equivalente a #!/bin/bash.

Dalla pagina man bash (1) :

"Se bash viene invocato con il nome sh, cerca di imitare il comportamento di avvio delle versioni storiche di sh il più vicino possibile, pur rispettando lo standard POSIX."

Ad esempio la sintassi specifica di bash:

 exec  > >(tee logfile.txt)

dà un errore in una shell a partire da #!/bin/sh, anche con il collegamento simbolico sh-> bash in posizione.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.