Quando scriviamo programmi di shell, spesso usiamo /bin/sh
e /bin/bash
. Io di solito uso bash
, ma non so quale sia la differenza tra loro.
Qual è la differenza principale tra bash
e sh
?
Di cosa dobbiamo essere consapevoli quando programmiamo in bash
e sh
?
sh
(o il linguaggio dei comandi della Shell) è un linguaggio di programmazione descritto dallo standard POSIX
standard.
Ha molte implementazioni (ksh88
, dash
, ...). Anche bash
può essere
considerata un'implementazione di sh
(vedi sotto).
Poiché sh
è una specifica, non un'implementazione, /bin/sh
è un symlink
(o un hard link) ad un'implementazione reale sulla maggior parte dei sistemi POSIX.
bash
ha iniziato come un'implementazione compatibile con sh
(anche se precede lo standard POSIX di qualche anno), ma col passare del tempo ha acquisito molte estensioni. Molte di queste estensioni possono cambiare il comportamento degli script di shell POSIX validi, quindi di per sé bash
non è una shell POSIX valida. Piuttosto, è un dialetto del linguaggio shell POSIX.
bash
supporta uno switch --posix
, che lo rende più conforme a POSIX. Cerca anche di imitare POSIX se invocato come sh
.
Per molto tempo, /bin/sh
puntava a /bin/bash
sulla maggior parte dei sistemi GNU/Linux. Di conseguenza, era quasi diventato sicuro ignorare la differenza tra i due. Ma questo ha iniziato a cambiare di recente.
Alcuni esempi popolari di sistemi dove /bin/sh
non punta a /bin/bash
(e su alcuni dei quali /bin/bash
potrebbe anche non esistere) sono:
sh
a dash
;initramfs
. Utilizza l'implementazione della shell ash
.pdksh
, un discendente della shell Korn. FreeBSD's sh
è un discendente dell'originale shell Bourne di UNIX. Solaris ha la propria sh
che per molto tempo non è stata conforme a POSIX; un'implementazione libera è disponibile dal progetto Heirloom.Come potete scoprire a cosa punta /bin/sh
sul vostro sistema?
La complicazione è che /bin/sh
potrebbe essere un link simbolico o un hard link.
Se è un link simbolico, un modo portatile per risolverlo è:
% file -h /bin/sh
/bin/sh: symbolic link to bash
Se si tratta di un collegamento fisso, provate
% find -L /bin -samefile /bin/sh
/bin/sh
/bin/bash
Infatti, il flag -L
copre sia i symlink che gli hardlink,
ma lo svantaggio di questo metodo è che non è portabile -
POSIX non richiede find
di supportare l'opzione -samefile
,
sebbene sia GNU find che FreeBSD find la supportino.
In definitiva, sta a voi decidere quale usare, scrivendo la linea «shebang».
Es.
#!/bin/sh
userà sh
(e tutto ciò a cui punta),
#!/bin/bash
userà /bin/bash
se è disponibile (e fallirà con un messaggio di errore se non lo è). Naturalmente, si può anche specificare un'altra implementazione, ad esempio
#!/bin/dash
Per i miei script, preferisco sh
per le seguenti ragioni:
bash
, sono obbligati ad avere sh
.Ci sono anche vantaggi nell'usare bash
. Le sue caratteristiche rendono la programmazione più conveniente e simile a quella di altri linguaggi di programmazione moderni. Queste includono cose come le variabili locali con scopo e gli array. Il semplice sh
è un linguaggio di programmazione molto minimalista.
sh
: http://man.cx/sh
bash
: http://man.cx/bash
TL;DR: bash
è un superset di sh
con una sintassi più elegante e più funzionalità. E' sicuro usare una linea shebang di bash in quasi tutti i casi in quanto è abbastanza onnipresente sulle piattaforme moderne.
NB: in alcuni ambienti, sh
è bash
. Controlla sh --versione
.
La Shell è un'interfaccia tra un utente e il sistema operativo per accedere ai servizi di un sistema operativo. Può essere sia GUI che CLI (Command Line interface).
sh (Bourne shell) è un interprete di shell a riga di comando, per sistemi operativi Unix/Unix-like. Fornisce alcuni comandi integrati. Nel linguaggio di scripting si indica l'interprete come #!/bin/sh
. Era quella più ampiamente supportata da altre shell come bash (libera/aperta), kash (non libera).
Bash (Bourne again shell) è un sostituto della shell Bourne. Bash è un superset di sh. Bash supporta sh. POSIX è un insieme di standard che definiscono come dovrebbero funzionare i sistemi conformi a POSIX. Bash non è in realtà una shell conforme a POSIX. In un linguaggio di scripting si indica l'interprete come #!/bin/bash
.
Analogia: