Quale shell esegue gli script quando non c'è nessuna riga shebang (#! / Path / to / shell) all'inizio? Presumo / bin / sh ma non posso confermare.
Il kernel si rifiuta di eseguire tali script e restituisce ENOEXEC, in modo che il comportamento esatto dipende dal programma che si esegue uno script da .
- bash 4.2.39 - usa se stesso
- busybox-ash 1.20.2 - usa se stesso
- trattino 0.5.7 - corre / bin / sh
- fish 1.23.1 - si lamenta di ENOEXEC, quindi incolpa il file sbagliato
- AT&T ksh 93u + 2012.08.01 - usa se stesso
- mksh R40f - corre / bin / sh
- pdksh 5.2.14 - run / bin / sh
- sh-heirloom 050706 - usa se stesso
- tcsh 6.18.01 - run / bin / sh
- zsh 5.0.0 - corre / bin / sh
- cmd.exe 5.1.2600 - ti guarda divertente.
In glibc , funzioni execv()
o execve()
semplicemente restituisce ENOEXEC. Ma execvp()
nasconde questo codice di errore e invoca automaticamente / bin / sh. (Questo è documentato in exec (3p) .)
Quali sono le "migliori pratiche" in termini di scrittura di script shell che verranno eseguiti su qualsiasi piattaforma? (ok, questo è un po 'aperto)
Attenersi sh
e solo alle funzionalità definite da POSIX o andare semplicemente alla bash (che è ampiamente disponibile) e menzionarlo nelle vostre esigenze se distribuirlo.
(Ora che ci penso, Perl - o forse Python - sarebbe ancora più portatile, per non parlare della migliore sintassi.)
Aggiungi sempre la linea shebang. Se usi bash o zsh, usa #!/usr/bin/env bash
invece di hardcoding il percorso della shell. (Tuttavia, la shell POSIX è garantita /bin/sh
, quindi saltare env
in quel caso.)
(Sfortunatamente, anche /bin/sh
non è sempre lo stesso. Il programma GNU autoconf deve affrontare molte stranezze diverse .)
È possibile scrivere uno script che tenti di usare zsh e torni a bash se zsh non è disponibile? Ho provato a mettere due righe di shebang, come di seguito, ma solo errori con un interprete errato: / bin / zsh: nessun file o directory simile se lo provo su una macchina senza zsh.
Ci può essere solo una linea shebang; tutto ciò che segue il carattere newline non viene nemmeno letto dal kernel e trattato come un commento da shell.
È possibile scrivere uno script che viene eseguito come #!/bin/sh
, controlla quale shell è disponibile e viene eseguita exec zsh "$0" "$@"
o in exec bash "$0" "$@"
base al risultato. Tuttavia, la sintassi utilizzata da bash e zsh è così diversa in vari punti che non consiglierei di farlo per la tua sanità mentale.