Hay varias formas de ejecutar un script, las que conozco son:
/path/to/script # using the path (absolute or relative)
. script # using the . (dot)
source script # using the `source` command
¿Son más de esto? Cuáles son las diferencias entre ellos? ¿Hay situaciones en las que debo usar una y no otra?
shell-script
executable
phunehehe
fuente
fuente
Respuestas:
Otra forma es llamar al intérprete y pasarle la ruta al script:
El punto y la fuente son equivalentes. (EDITAR: no, no lo son: como KeithB señala en un comentario sobre otra respuesta, "." Solo funciona en shells relacionados con bash, donde "source" funciona en shells relacionados con bash y csh). Ejecuta el script en -place (como si hubiera copiado y pegado el script allí). Esto significa que las funciones y variables no locales en el script permanecen. También significa que si el script hace un CD en un directorio, todavía estará allí cuando esté listo.
Las otras formas de ejecutar un script lo ejecutarán en su propia subshell. Las variables en el script aún no están vivas cuando se hace. Si el script cambió de directorio, entonces no afecta el entorno de llamada.
/ path / to / script y / bin / sh script son ligeramente diferentes. Típicamente, un script tiene un "shebang" al principio que se ve así:
Este es el camino hacia el intérprete de guiones. Si especifica un intérprete diferente que cuando lo ejecuta, puede comportarse de manera diferente (o puede no funcionar en absoluto).
Por ejemplo, los scripts de Perl y Ruby comienzan con (respectivamente):
y
Si ejecuta uno de esos scripts ejecutando
/bin/sh script
, entonces no funcionarán en absoluto.Ubuntu en realidad no usa el shell bash, sino uno muy similar llamado dash. Las secuencias de comandos que requieren bash pueden funcionar un poco mal cuando se llama haciendo
/bin/sh script
porque acaba de llamar una secuencia de comandos bash utilizando el intérprete de guiones.Otra pequeña diferencia entre llamar al script directamente y pasar la ruta del script al intérprete es que el script debe estar marcado como ejecutable para ejecutarlo directamente, pero no para ejecutarlo pasando la ruta al intérprete.
Otra variación menor: puede prefijar cualquiera de estas formas de ejecutar un script con eval, por lo tanto, puede tener
y así. En realidad no cambia nada, pero pensé que lo incluiría por minuciosidad.
fuente
sh
corresponde adash
, pero no abash
.La mayoría de las personas depuran los scripts de shell agregando los siguientes indicadores de depuración al script:
Pero esto significa que debe abrir el archivo con un editor (suponiendo que tenga permisos para editar el archivo), agregar una línea como
set -x
, guardar el archivo y luego ejecutar el archivo. Luego, cuando haya terminado, debe seguir los mismos pasos y eliminarset -x
, etc., etc. Esto puede ser tedioso.En lugar de hacer todo eso, puede establecer los indicadores de depuración en la línea de comandos:
fuente
emulate sh 2>/dev/null
en la parte superior de mis scripts de shell. Cuando se ejecuta con zsh, esto lo pone en modo compatible con POSIX. Cuando se ejecuta con otros proyectiles, la línea no tiene efecto. Entonces puedo ejecutar el script conzsh -x /path/to/script
. Me gusta zsh aquí porque proporciona mejores trazas que bash o ksh.Shawn J. Goff hizo muchos puntos buenos, pero no incluyó toda la historia:
Muchas secuencias de comandos del sistema (como en init.d, en / etc, etc.) tienen un shebang
#!/bin/sh
, pero/bin/sh
de hecho es un enlace simbólico a otro shell, en tiempos/bin/bash
pasados, hoy en día/bin/dash
. Pero cuando uno de ellos se invoca como/bin/sh
, se comportan de manera diferente, es decir, se adhieren al modo de compatibilidad POSIX.¿Cómo lo hacen? Bueno, inspeccionan cómo fueron invocados.
¿Puede un shellscript probar cómo se invocó y hacer diferentes cosas, dependiendo de eso? Sí puede. Entonces, la forma en que lo invocas siempre puede conducir a resultados diferentes, pero, por supuesto, rara vez se hace para molestarte. :)
Como regla general: si está aprendiendo un shell específico como bash y escribe comandos de un tutorial de bash, coloque
#!/bin/bash
el título, no#!/bin/sh
, excepto donde se indique lo contrario. De lo contrario, sus comandos podrían fallar. Y si no ha escrito un guión usted mismo, invoque directamente (./foo.sh
,bar/foo.sh
) en lugar de adivinar un shell (sh foo.sh
,sh bar/foo.sh
). El shebang debería invocar el caparazón correcto.Y aquí hay otros dos tipos de invocación:
fuente
.
ysource
son equivalentes porque no generan un subproceso sino que ejecutan comandos en el shell actual. Esto es importante cuando el script establece variables de entorno o cambia el directorio de trabajo actual.Usar la ruta o dársela
/bin/sh
crea un nuevo proceso en el que se ejecutan comandos.fuente
Estoy pensando si hay más ...
.
ysource
son lo mismo Después de la ejecución, cualquier cambio de entornoscript
se mantendría. Por lo general, se usaría para obtener una biblioteca Bash, por lo que la biblioteca se puede reutilizar en muchos scripts diferentes.También es una buena manera de mantener el directorio actual. Si cambia el directorio en el script, no se aplicará en el shell donde ejecuta ese script. Pero si lo busca para ejecutarlo, después de que el script salga, se mantendrá el directorio actual.
fuente
.
solo funciona en sh / bash y shells relacionados.source
También funciona en csh y shells relacionados.¿" Userland exec " cuenta como una forma diferente? Userland exec carga el código y lo ejecuta sin el uso de una llamada al sistema execve ().
fuente
Ejecuta el script en el shell actual cuando el directorio no está en la ruta.
fuente
. y la fuente son un poco diferentes en zsh al menos (eso es lo que uso) porque
Funciona, mientras
no, necesita
fuente