¿Cómo ejecutar un script de shell en una consola Unix o terminal Mac?
Lo sé, lo olvido y lo reaprendo. Es hora de escribirlo.
Para ejecutar un script no ejecutable sh
, utilice:
sh myscript
Para ejecutar un script no ejecutable bash
, utilice:
bash myscript
Para iniciar un ejecutable (que es cualquier archivo con permiso ejecutable); simplemente lo especificas por su ruta:
/foo/bar
/bin/bar
./bar
Para hacer que un script sea ejecutable, dale el permiso necesario:
chmod +x bar
./bar
Cuando un archivo es ejecutable, el núcleo es responsable de descubrir cómo ejecutarlo. Para archivos no binarios, esto se hace mirando la primera línea del archivo. Debe contener un hashbang
:
#! /usr/bin/env bash
El hashbang le dice al kernel qué programa ejecutar (en este caso el comando /usr/bin/env
se ejecuta con el argumento bash
). Luego, el script se pasa al programa (como segundo argumento) junto con todos los argumentos que le dio al script como argumentos posteriores.
Eso significa que cada script ejecutable debe tener un hashbang . Si no es así, no le estás diciendo al kernel qué es y, por lo tanto, el kernel no sabe qué programa usar para interpretarlo. Podría ser bash
, perl
, python
, sh
o algo más. (En realidad, el kernel a menudo utilizará el shell predeterminado del usuario para interpretar el archivo, lo cual es muy peligroso porque podría no ser el intérprete correcto en absoluto o podría analizar parte del mismo, pero con sutiles diferencias de comportamiento, como es el caso entre sh
y bash
).
una nota sobre/usr/bin/env
Lo más común es que veas hash bangs así:
#!/bin/bash
El resultado es que el kernel ejecutará el programa /bin/bash
para interpretar el script. Lamentablemente, bash
no siempre se envía de forma predeterminada y no siempre está disponible en formato /bin
. Si bien en las máquinas Linux suele ser así, hay una variedad de otras máquinas POSIX que bash
se envían en varias ubicaciones, como /usr/xpg/bin/bash
o /usr/local/bin/bash
.
Por lo tanto, para escribir un script bash portátil, no podemos confiar en codificar la ubicación del bash
programa. POSIX ya tiene un mecanismo para lidiar con eso: PATH
. La idea es que instales tus programas en uno de los directorios que se encuentran PATH
y el sistema debería poder encontrar tu programa cuando quieras ejecutarlo por su nombre.
Lamentablemente, no puedes simplemente hacer esto:
#!bash
El kernel no hará (algunos podrían) realizar una PATH
búsqueda por usted. Sin embargo, existe un programa que puede realizar una PATH
búsqueda por usted: se llama env
. Por suerte, casi todos los sistemas tienen un env
programa instalado en formato /usr/bin
. Entonces comenzamos env
a usar una ruta codificada, que luego la PATH
busca bash
y la ejecuta para que pueda interpretar su script:
#!/usr/bin/env bash
Este enfoque tiene una desventaja: según POSIX, el hashbang puede tener un argumento . En este caso, lo utilizamos bash
como argumento del env
programa. Eso significa que no nos queda espacio para pasarle argumentos bash
. Entonces no hay forma de convertir algo como #!/bin/bash -exu
este esquema. En su lugar , tendrás que ponerlo set -exu
después del hashbang.
Este enfoque también tiene otra ventaja: algunos sistemas pueden venir con un /bin/bash
, pero al usuario puede no gustarle, puede encontrarlo defectuoso o anticuado y puede haber instalado el suyo propio bash
en otro lugar. Este suele ser el caso en OS X (Mac), donde Apple envía una versión desactualizada /bin/bash
y los usuarios instalan una versión actualizada /usr/local/bin/bash
usando algo como Homebrew. Cuando utiliza el env
enfoque que realiza una PATH
búsqueda, tiene en cuenta las preferencias del usuario y utiliza su bash preferido sobre el que viene con su sistema.
Para iniciar el script de shell 'file.sh':
sh file.sh
bash file.sh
Otra opción es establecer permisos ejecutables usando el comando chmod:
chmod +x file.sh
Ahora ejecute el archivo .sh de la siguiente manera:
./file.sh
Para el shell Bourne:
sh myscript.sh
Para fiesta:
bash myscript.sh