Risposte:
Se usi
sh ./<script>.run
/bin/sh
(di solito una shell Bourne) verrà utilizzato per eseguire lo script. Ovviamente questo funziona solo se lo script è scritto per la shell Bourne. A volte gli script di shell per Linux richiedono Bash anziché Bourne shell, quindi potrebbe non funzionare anche se si tratta di uno script di shell.
Se usi
./<script>.run
il kernel guarda la linea shebang per scoprire quale programma usare per eseguirlo. Quindi funziona anche se è un Bash, Perl, Python o qualche altro script.
Quindi questo è di solito il modo preferito per eseguire uno script.
Finché si tratta di uno sh
script di shell (tratteggiato o equivalente), no, non vi è alcuna differenza esteriore.
Il problema è .run
che non è questo il caso. Potrebbe essere binario. Potrebbe essere Bash o Python o PHP o altro; hanno tutti un hash-bang di script di shell. Se lo costringi ciecamente attraverso sh
, chissà cosa potrebbe accadere. Probabilmente andrà in errore ma potrebbe accidentalmente eseguire codice dannoso prima di arrivare così lontano.
Con chmod
ding esso (per abilitare il bit di permesso di esecuzione) e poi eseguirlo ./script.run
, è dare la possibilità migliore possibile di correre. Se è uno script di shell, il suo hash-bang verrà analizzato correttamente e se è un eseguibile binario, verrà eseguito in modo nativo.
I due metodi possono spesso agire allo stesso modo ma sono molto diversi.
sh ./script
esegue il sh
comando con un argomento ./script
, che accade per eseguire lo script dato .. anche se lo script non è in realtà uno sh
script (non valido)
./script
esegue il file indicato. Lo fa cercando la riga "shebang" per determinare quale comando eseguire. Se non specificato utilizza sh
(questo a volte i due metodi si comportano allo stesso modo), ma spesso viene specificato un interprete diverso.
Ad esempio, se filename
contiene quanto segue:
#!/usr/bin/python
print "This is a Python script!"
.. quindi i due comandi sono molto diversi:
$ sh script
script: line 3: print: command not found
$ chmod +x script
$ ./script
This is a Python script!
Se non esiste una linea shebang, i due sono gli stessi:
$ cat script
echo "This is an sh script"
$ sh ./script
This is an sh script
$ ./script
This is an sh script
Una differenza importante è se la tua linea hashbang ha parametri. Ad esempio, se lo script inizia con
#!/bin/bash -e
... e lo esegui esternamente utilizzando sh
o bash
, quella riga verrà interpretata come un commento e ignorata, quindi il -e
parametro (uscita in caso di errore) non verrà elaborato. Quindi, dato il seguente script:
#!/bin/bash -e
echo Hello
false
echo goodbye
L'output per ./script
sarà solo "Hello", ma l'output per sh script
sarà Hello
seguito da goodbye
, che probabilmente non era previsto.
Questo, a proposito, è il motivo per cui dovresti sempre usare set -e
un'istruzione separata (è comunque una buona idea - il più delle volte, se c'è un problema a metà script, non vorrai che venga ignorato).