# Shabang

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, "/bin/sh", che è solitamente l'interprete specificato.

## Storia

Lo shabang fu introdotto da Dennis Ritchie tra la versione 7 di Unix e la versione 8 nei Bell Labs. Fu quindi aggiunta a BSD a Berkeley. Dato che la versione 8 e successive non furono distribuite al pubblico, la prima diffusione di massa dello shabang avvenne proprio su BSD.

## Caratteristiche

Precisamente, consiste in un magic number (il carattere cancelletto e il punto esclamativo "#!"), seguito dal pathname assoluto dell'interprete da utilizzare. Lo shabang viene utilizzato in modo che lo script appaia e funzioni agli occhi dell'utente come un qualsiasi altro file eseguibile nativo per la piattaforma.
Dato che nei linguaggi di scripting il carattere "#" indica comunemente l'inizio di una linea di commento, l'interprete ignorerà il contenuto della riga che contiene in incipit lo shabang; la linea esiste infatti soltanto per indicare quale interprete è necessario, e concettualmente non fa parte dello script.

## Portabilità

Mentre molti shabang indicano interpreti che hanno pathname standard ben noti, è anche possibile che tra varianti di uno stesso sistema operativo lo stesso interprete vada indicato con pathname differenti. In assenza di una rigida standardizzazione delle posizioni di ciascun interprete, ci possono essere problemi dovuti al fatto che lo shabang potrebbe richiedere un interprete che non esiste, o che non si trova nel posto indicato. Questo limita la portabilità del file.
Per questo motivo, nel passaggio da computer a computer, è spesso necessario modificare lo script proprio per permettere la portabilità tra sistemi diversi. Questa è una delle ragioni per cui lo standard POSIX non prevede questa caratteristica, che è però comunemente utilizzata, soprattutto a livello didattico. Spesso il comando env può essere usato per aggirare il problema.
Un altro problema di portabilità è legato alla gestione di eventuali parametri specificati all'interprete, in quanto alcuni sistemi hanno possibilità limitate al riguardo. Ad esempio sui sistemi basati su Linux lo shabang
verrà eseguito come /usr/bin/env "perl -w", con "perl" e "-w" uniti in un unico parametro a /usr/bin/env e questo causa un errore:
Altri sistemi possono comportarsi in modo ancora diverso.

## Shabang come numero magico

Lo shabang è di fatto una versione leggibile di un magic number nel file eseguibile. La stringa magica diviene la sequenza di byte 0x23 0x21 all'inizio del file, che corrisponde appunto alla rappresentazione secondo la codifica ASCII dei caratteri "#!".
I file eseguibili che non richiedono interpreti hanno invece altri magic number.

## Esempi
### Script di shell

Esegue usando Bash:
Esegue usando la shell /bin/sh. Su molti dei sistemi Unix e Unix-like questa è una shell POSIX (ad esempio su HP-UX, AIX ed anche su GNU/Linux, dove Bash si comporta come una shell POSIX se invocata con questo nome), mentre su Solaris è invece una Bourne shell:
Esegue usando Korn shell:
Esegue usando csh, la C shell:

### Script Perl

Esegue usando Perl:
Esegue usando Perl, ma si assume che l'interprete Perl sia in un'altra directory:

### Script Python

Esegue usando Python:
Esegue usando Python versione 3:

### Script Ruby

Esegue usando Ruby:

### Script Tcl

Esegue uno script Tcl invocando l'interprete attraverso /bin/sh:
Questo metodo sfrutta una particolarità del linguaggio Tcl: se una linea di commento termina con una barra inversa ("\"), allora il commento prosegue anche sulla linea successiva, mentre ciò non è vero per la shell.
Di fatto lo script viene avviato una prima volta tramite /bin/sh, che ignora la linea di commento e procede ad eseguire il comando "exec tclsh "$0" "$@"", che ricerca tclsh nelle directory elencate nella variabile d'ambiente $PATH e lo invoca passandogli il pathname dello script e tutti i parametri specificati, sostituendolo al processo della shell. L'interprete Tcl a questo punto inizia a leggere lo script, considera come un commento tutte e tre le linee, e procede quindi ad esaminare le linee successive.

### Altri script

Esegue usando l'interprete Awk presente nella directory /bin/. Notare l'uso dell'opzione -f, altrimenti lo script verrebbe considerato come file di testo di input da elaborare (invece che le istruzioni AWK da eseguire):
Esegue usando Lua:
Esegue usando l'interprete PHP:

### Invocazione con parametri e opzioni

In molti sistemi si può indicare di seguito all'interprete un parametro o una opzione, ed in alcuni di essi anche più parametri e/o opzioni. Tuttavia, implementazioni diverse hanno comportamenti e vincoli diversi: ad esempio in molti sistemi, tra cui quelli basati su Linux, tutto ciò che segue l'interprete è passato come un unico parametro anche se contiene spazi, mentre su altri sistemi vi sono limitazioni sulla lunghezza complessiva dello shabang.
Esegue usando l'interprete AWK, e ad esso viene passata anche l'opzione -f:
Esegue usando l'interprete Perl, e ad esso viene passata anche l'opzione -w per ottenere i messaggi di warning:
Esegue usando bash, indicando con l'opzione -x di mostrare ogni comando subito prima di eseguirlo:

### Risoluzione di problemi legati allo shabang tramite env

L'invocazione tramite env è utile in quanto diventa possibile specificare un interprete non conoscendo il suo pathname assoluto. env infatti cerca l'interprete nelle directory specificate nella variabile d'ambiente $PATH.
Ad esempio, supponendo di non sapere con precisione dove è installato l'interprete Perl:
Nonostante questo metodo aumenti di molto la portabilità, esso non è infallibile: mentre env è quasi sempre disponibile in /usr/bin/env, in un numero ristretto di piattaforme si trova in /bin/env. In questo caso, come nel caso in cui si indichi un qualsiasi path non coerente con le impostazioni generali del sistema operativo, l'interprete dei comandi (il terminale) restituisce un errore e non esegue lo script.
Inoltre, sui sistemi che non separano tra di loro i parametri specificati di seguito all'interprete (che in questo caso è /usr/bin/env) diventa impossibile specificare parametri all'interprete vero e proprio.

### Altri esempi

Questo è un quine, ovvero un file che produce in output sé stesso attraverso il comando cat:
Questo script non fa altro che scrivere all'infinito il nome con cui è invocato:
Questo script non fa altro che auto-cancellarsi, usando rm come interprete: