Lo standard POSIX (Single UNIX Specification 4) non è utile:
Se la prima riga di un file di comandi shell inizia con i caratteri "#!" , i risultati non sono specificati.
Quindi, lo standard implica che se non hai #! quindi dovrebbe eseguire una shell POSIX. Ma le shell moderne non sono conformi a POSIX. La vecchia Korn Shell 88 (ksh88) eseguiva la shell Bourne (vicino a una shell POSIX) senza #! line, ma ksh93 lo interrompe, e anche Bash. Sia con ksh93 che con Bash, eseguono la propria shell se no #! la linea è presente.
Nonostante l'opinione popolare, le conchiglie Bash e Korn differiscono. Quando scrivi uno script di shell non puoi mai essere sicuro da quale shell verrai eseguito, o anche se verrà eseguito da un'altra shell (la maggior parte dei linguaggi di programmazione può eseguire altri programmi). Nel momento in cui usi qualcosa al di fuori della sintassi Bourne/POSIX verrai fatto naufragare.
Usa sempre un #! line, non lasciarlo al caso.
La shell madre, dove hai inserito ./myscript.sh
, prima ho provato a execve
it, che è dove la linea Shebang entrerebbe in vigore se presente. Quando funziona, il genitore non è a conoscenza della differenza tra script ed ELF perché il kernel se ne occupa.
Il execve
fallito, quindi è stata attivata un'antica funzionalità di compatibilità unix, precedente all'esistenza delle linee shebang. Ha ipotizzato che un file che ha il permesso di esecuzione ma non è riconosciuto come file eseguibile valido dal kernel debba essere uno script di shell.
Di solito la shell madre suppone che lo script sia scritto per la stessa shell (le shell minime simili a Bourne eseguono lo script con /bin/sh
, bash lo esegue come un sottoprocesso bash), csh fa alcune ipotesi più complicate basate sul primo carattere perché è antecedente anche a shebang e doveva coesistere con Bourne shell).
Hai bisogno di una linea shebang quando sai che queste ipotesi saranno sbagliate (ad esempio con shebang è #!/usr/bin/perl
), o quando non ritieni che l'ipotesi funzioni in modo coerente, o quando lo script deve essere eseguito da un processo padre che non sia esso stesso una shell.
la linea shebang è necessaria in il file e solo se deve essere eseguito come eseguibile (al contrario di sh file.sh
invocazione. In realtà non è necessario allo script, spetta al sistema sapere come trovare l'interprete.
MODIFICA :Ci scusiamo per aver letto male la domanda. Se la linea shebang è mancante o non riconosciuta, /bin/sh
viene usato. Ma preferisco essere esplicito sull'interprete.
Nota che questo comportamento non è universale, IIRC, solo alcuni exec*
la funzione familiare lo fa (per non parlare delle diverse piattaforme), quindi questa è un'altra ragione per essere espliciti qui.