¿Hay alguna diferencia real entre ejecutar un script con
[sudo] sh ./<script>.run
en lugar de
[sudo] chmod +x ./<script>.run
[sudo] ./<script>.run
¿Hay alguna diferencia real entre ejecutar un script con
[sudo] sh ./<script>.run
en lugar de
[sudo] chmod +x ./<script>.run
[sudo] ./<script>.run
Respuestas:
Si utiliza
sh ./<script>.run
/bin/sh
(generalmente un shell Bourne) se usará para ejecutar el script. Por supuesto, esto solo funciona si el script está escrito para Bourne Shell. A veces, los scripts de shell para Linux requieren Bash en lugar de Bourne, por lo que esto puede no funcionar incluso si se trata de un script de shell.
Si utiliza
./<script>.run
el núcleo mira la línea shebang para averiguar qué programa usar para ejecutar el programa. Entonces esto funciona incluso si es un Bash, Perl, Python o algún otro script.
Por lo tanto, esta suele ser la forma preferida de ejecutar un script.
Siempre que sea un sh
script de shell (Dash o equivalente), no, no hay diferencia externa.
El problema es .run
que no garantiza que ese sea el caso. Podría ser binario. Podría ser Bash o Python o PHP o lo que sea; todos tienen un script de shell hash-bang. Si lo forzas ciegamente sh
, quién sabe qué podría pasar. Probablemente se producirá un error, pero podría ejecutar accidentalmente código dañino antes de llegar tan lejos.
Al chmod
activarlo (para habilitar el bit de permiso de ejecución) y luego ejecutarlo ./script.run
, le brinda la mejor posibilidad de ejecución. Si es un script de shell, su hash-bang se analizará correctamente y si es un ejecutable binario, simplemente se ejecutará de forma nativa.
Los dos métodos a menudo pueden actuar igual pero son muy diferentes.
sh ./script
ejecuta el sh
comando con un argumento ./script
que ejecuta el script dado ... incluso si el script no es realmente un sh
script (incorrecto)
./script
Ejecuta el archivo dado. Lo hace buscando la línea "shebang" para determinar qué comando ejecutar. Si no se especifica, utiliza sh
(a veces los dos métodos actúan igual), pero a menudo se especifica un intérprete diferente.
Por ejemplo, si filename
contiene lo siguiente:
#!/usr/bin/python
print "This is a Python script!"
..entonces los dos comandos son muy diferentes:
$ sh script
script: line 3: print: command not found
$ chmod +x script
$ ./script
This is a Python script!
Si no hay una línea shebang, los dos son iguales:
$ cat script
echo "This is an sh script"
$ sh ./script
This is an sh script
$ ./script
This is an sh script
Una diferencia importante es si su línea hashbang tiene parámetros. Por ejemplo, si el script comienza con
#!/bin/bash -e
... y lo ejecuta externamente usando sh
o bash
, esa línea se interpretará como un comentario y se ignorará, por lo que el -e
parámetro (salir en caso de falla) no se procesará. Entonces, dado el siguiente script:
#!/bin/bash -e
echo Hello
false
echo goodbye
La salida para ./script
será solo "Hola", pero la salida para sh script
será Hello
seguida por goodbye
, lo que probablemente no fue intencionado.
Por cierto, esta es la razón por la que siempre debe usar una set -e
declaración separada (de todos modos, es una buena idea; la mayoría de las veces, si hay un problema a mitad del script, no querrá que se ignore).