Gli script probabilmente hanno terminazioni di riga CR-LF in stile DOS e non terminazioni di riga LF in stile Unix. La ^ M vista nel messaggio di errore nel primo caso indica che il carattere 0D è stato interpretato come parte del nome dell'interprete dello script e non come parte della fine della linea (come ci si potrebbe aspettare che sia). Poiché sul sistema non è presente alcun file eseguibile con un percorso che includa il carattere 0D (^ M), il sistema non è in grado di richiamare l'interprete. Quando chiami manualmente l'interprete, è in grado di gestire entrambi i tipi di terminazioni di linea presenti nello script.
Se converti gli script per utilizzare i finali di linea LF in stile Unix, dovresti vedere che shebang funziona. Continua a leggere per un'illustrazione.
Nella sessione seguente, todos e fromdos sono un'utilità (disponibile su Ubuntu come pacchetto tofrodos
) per convertire le convenzioni di fine linea da CR-LF a LF. Qualsiasi utilità equivalente (vedi questa domanda unix.SE ) farebbe a scopo dimostrativo.
La seguente trascrizione della sessione (eseguita con gli stessi file di script) dovrebbe chiarire la situazione:
$ fromdos hello.sh
$ ./hello.sh
Hello
$ todos hello.sh
$ ./hello.sh
bash: ./hello.sh: /bin/sh^M: bad interpreter: No such file or directory
$
$ fromdos hello.py
$ ./hello.py
Hello
$ todos hello.py
$ ./hello.py
: No such file or directory
$
E sembra che sia il kernel che legge la linea shebang, ea quanto pare il kernel Linux (almeno a partire dalla versione sul mio sistema Saucy Kubuntu) non riconosce il CR come parte della linea di CR-LF fine convenzione.
Se lo shebang del tuo script non sembra funzionare (cioè chiamando manualmente l'interprete sullo script funziona ma non puoi eseguire lo script usando il nome del suo file anche se lo hai fatto chmod +x
), allora questo è un possibile motivo.
NOTA:
grazie anche agli altri che hanno commentato. Sarei anche felice di sapere se ci sono risposte migliori!