Se siete qui probabilmente avete avuto davanti almeno una volta uno script da eseguire nel terminale di linux o macOS, ed avete notato che la prima riga è sempre #!/bin/bash o #!/bin/sh. Ma cos’è questa riga? Cosa significa e se devo scrivere uno script nuovo, quale devo usare? Quando si usa #!/bin/bash? Quando è meglio usare #!/bin/sh? Cerchiamo di fare un po’ di chiarezza e capire meglio!
Indice
- Cos’è #!/bin/bas e #!/bin/sh? lo shabang
- A cosa serve #!/bin/bash o #!/bin/sh?
- Quando usare #!/bin/bash e quando #!/bin/sh?
- Quando usare #!/bin/sh
- Quando usare #!/bin/bash
- Conclusioni
Cos’è #!/bin/bas e #!/bin/sh? lo shabang
Per prima cosa cerchiamo di dare un nome a questa sequenza di caratteri. Una volta definito correttamente probabilmente sarà più chiaro anche il significato e perché si trova li.
La sequenza di caratteri che troviamo nella prima riga della maggior parte degli script per shell linux/unix si chiama Shabang. Vediamo cosa ci dice su questa parola wikipedia:
Uno shabang (chiamato anche shebang, hashbang, hashpling, o pound bang), nei sistemi operativi Unix e Unix-like, è una sequenza di caratteri che inizia per “
#!
” collocata esattamente all’inizio di uno script, la quale indica al sistema quale interprete utilizzare per eseguire lo script stesso.Il termine deriverebbe da una contrazione di SHArp bang o haSH bang, che rappresentano i nomi tradizionalmente usati in ambienti Unix per riferirsi ai due caratteri in questione. Un’altra teoria sul sh di shabang deriva dalla shell testuale standard, “
Wikipedia – Shabang/bin/sh
“, che è solitamente l’interprete specificato
Da questa definizione iniziamo quindi a capire che lo shabang inizia sempre per #!
, e che si deve trovare sempre all’inizio dello script, non possiamo quindi utilizzarlo in altri punti.
A cosa serve #!/bin/bash o #!/bin/sh?
Dalla definizione precedente possiamo anche iniziare a capire a cosa serve #!/bin/bash all’inizio di uno script. Leggiamo infatti che lo Shabang “indica al sistema quale interprete utilizzare per eseguire lo script”.
Solitamente siamo abituati ad aprire il terminale e inserire li i comandi, ma sotto la semplice interfaccia della linea di comando c’è molto di più… Il terminale è infatti in grado di interpretare ed eseguire script e comandi anche molto complessi. In più dobbiamo aggiungere che non tutti i terminali sono uguali, o meglio esistono diversi interpreti shell, e diversi sistemi o configurazioni possono avere interpreti diversi. Ma a questo punto come è possibile far si che gli script vengano interpretati nello stesso modo su macchine e sistemi operativi differenti? Proprio per cercare di risolvere questo problema ci vengono in aiuto lo standard POSIX e lo Shabang.
Lo standard POSIX
Lo standard POSIX è una famiglia di standard, definiti intorno al 1985, che cerca proprio di rendere standard le interfacce utilizzate dai sistemi operativi unix. Una shell nel nostro caso si può dire che sia standard POSIX se contiene tutti i comandi definiti in questo standard e questi si comportano nel modo definito dallo standard. Come vedremo non tutte le shell implementano lo standard POSIX, ma utilizzando un terminale standard avremo la certezza che il nostro script possa essere eseguito senza problemi su altre shell che rispettano lo standard.
Lo Shabang
Lo shabang, come abbiamo già iniziato a capire, ha la funzione di indicare al sistema operativo che si appresta ad eseguire lo script, quale interprete shell dovrà utilizzare per eseguire il nostro script. In questo modo potremo essere sicuri che il nostro script sia interpretato ed eseguito possibilmente sempre dallo stesso interprete e quindi produca l’output atteso.
Quando usare #!/bin/bash e quando #!/bin/sh?
A questo punto dovremo avere abbastanza chiaro cos’è lo standard POSIX e a cosa serve lo shabang, decidiamo di scrivere il nostro primo script shell… ci ritroviamo davanti ad un editor vuoto e dobbiamo scrivere questa famigerata prima riga. Cosa ci dobbiamo scrivere? #!/bin/bash come abbiamo visto in alcuni script? Oppure #!/bin/sh come in altri?
La risposta a questa domanda può essere un’altra domanda: Cosa ci dobbiamo fare con lo script che ci accingiamo a scrivere? Se avremo necessità di eseguirlo solamente sul nostro computer dovremo porci dei problemi, se dovremo darlo ad un amico altri, se vorremo distribuirlo su larga scala senza sapere su che sistemi operativi e con che configurazioni verrà eseguito dovremo fare delle altre considerazioni.
Nel primo caso ad esempio (script che dobbiamo eseguire solamente sul nostro computer) ci basterà accertarci che lo script funzioni con la nostra configurazione senza farci troppi problemi aggiuntivi.
Per il resto dei casi, se non sappiamo chi dovrà eseguire lo script cerchiamo di capire più nel dettaglio quando usare bin bash e quando bin sh.
Quando usare #!/bin/sh
/ bin /sh in praticamente tutte le distribuzioni linux rappresenta la shell di sistema. Più precisamente di solito a questo percorso corrisponde un collegamento simbolico che punta all’eseguibile reale della shell di sistema. La shell di sistema è la shell predefinita del sistema che tutti gli script in teoria dovrebbero usare. Per lungo tempo nelle varie distribuzioni linux la shell di sistema è stata un collegamento simbolico a bash. Per questo motivo si è iniziato quasi a dare per scontato che /bin/sh corrispondesse a /bin/bash. Negli ultimi anni però, la famiglia di distribuzioni di Debian e Ubuntu ha iniziato ad utilizzare dash (con la d) come shell di sistema, rompendo di fatto la convenzione non scritta in atto.
Dash è stata scelta al posto di bash perché ritenuta più veloce, e leggera. Le due shell sono in larga parte compatibili, essendo entrambe basate sullo standard POSIX. Bash però implementa delle estensioni aggiuntive che non sono presenti in dash. Il fatto di aver dato per scontato per lungo tempo che /bin/sh fosse di fatto /bin/bash ha portato alla scrittura di molti script che utilizzano lo shabang #!/bin/sh ma utilizzano alcune delle caratteristiche proprie di bash. Questo fa si che si creino problemi nei casi (come le recenti versioni di debian e ubuntu) in cui a /bin/sh non corrisponde /bin/bash.
Per queste motivazioni è preferibile utilizzare #!/bin/sh quando scriviamo uno script che utilizzi funzioni compatibili POSIX, ma non le estensioni aggiuntive presenti solamente in bash. In questo modo daremo al sistema operativo la possibilità di eseguire il nostro script con una shell di sistema diversa da bash (perché ritenuta più performante o più adatta alla particolare configurazione della macchina specifica) sapendo che lo script verrà eseguito correttamente senza errori.
In pratica #!/bin/sh dovrebbe essere la scelta predefinita per permettere al sistema di eseguire lo script nel proprio ambiente, a meno che non sia necessario utilizzare qualche funzionalità specifica, non appartenente allo standard POSIX, di una shell in particolare.
Quando usare #!/bin/bash
Lo shabang #!/bin/bash indica che lo script deve essere eseguito dalla shell bash, anche se questa non è la shell di sistema della macchina su cui lo stiamo lanciando. Questo ci permette di assicurarci che il nostro script sia sempre eseguito da questa shell e non da altre.
Utilizzeremo quindi questo shabang in tutti i casi in cui nel nostro script si fa uso delle estensioni aggiuntive presenti solamente nella shell bash. In questo modo, anche se la shell di sistema è dash come nel caso delle recenti distribuzioni di debian e ubunt, il nostro script sarà eseguito con la shell che supporta tutte le funzionalità richieste.
Conclusioni
Abbiamo quindi visto cosa sono #!/bin/sh e #!/bin/bash che troviamo all’inizio di tutti gli script linux, a cosa servono e quando è meglio usare uno o l’altro.
Per riassumere in poche parole possiamo dire che conviene utilizzare #!/bin/bash solamente quando utilizziamo le estensioni aggiuntive della shell bash. In tutti gli altri casi in cui lo script è compatibile con lo standard POSIX è raccomandabile utilizzare #!/bin/sh. L’assunto storico che #!/bin/sh corrisponde sempre a #!/bin/bash purtroppo non è più valido e quindi non più utilizzabile.