GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cuál es la diferencia entre ejecutar un script Bash y obtenerlo?

Abastecimiento un script ejecutará los comandos en el actual proceso de shell.

Ejecutando un script ejecutará los comandos en un nuevo proceso de shell.

Use la fuente si desea que el script cambie el entorno en su shell que se está ejecutando actualmente. use ejecutar de lo contrario.

el "entorno" son cosas como el directorio de trabajo actual y las variables de entorno. también la configuración de shell (entre otras funciones de historial y finalización). hay más pero esos son los más visibles.

Si desea obtener más detalles, siga leyendo.

Terminología

Para aclarar algunas confusiones comunes sobre la sintaxis a ejecutar y la sintaxis a la fuente:

./myscript

Esto ejecutará myscript siempre que el archivo sea ejecutable y esté ubicado en el directorio actual. El punto inicial y la barra inclinada (./ ) denota el directorio actual. Esto es necesario porque el directorio actual generalmente no está (y generalmente no debería estar) en $PATH .

myscript

Esto ejecutará myscript si el archivo es ejecutable y está ubicado en algún directorio en $PATH .

source myscript

Esto fuente myscript . No es necesario que el archivo sea ejecutable, pero debe ser un script de shell válido. El archivo puede estar en el directorio actual o en un directorio en $PATH .

. myscript

Esto también fuente myscript . Esta "ortografía" es la oficial definida por POSIX. Bash definió source como un alias al punto.

y para completar:

exec myscript

Esto terminará el shell actual y luego ejecutará myscript en lugar del shell terminado. Eso significa que cuando myscript está terminado, no hay un shell antiguo al que volver. exec es poderoso pero rara vez se necesita.

Pongo algunos enlaces al final para más información sobre estos temas.

Demostración

Considera myscript.sh con el siguiente contenido:

#!/bin/sh
# demonstrate setting a variable
echo "foo: "$(env | grep FOO)
export FOO=foo
echo "foo: "$(env | grep FOO)
# demonstrate changing of working directory
echo "PWD: "$PWD
cd somedir
echo "PWD: "$PWD

Antes de ejecutar el script primero verificamos el entorno actual:

$ env | grep FOO
$ echo $PWD
/home/lesmana

La variable FOO no está definido y estamos en el directorio de inicio.

Ahora ejecutamos el archivo:

$ ./myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir

Comprueba el entorno de nuevo:

$ env | grep FOO
$ echo $PWD
/home/lesmana

La variable FOO no está configurado y el directorio de trabajo no cambió.

El resultado del script muestra claramente que se configuró la variable y se cambió el directorio. La verificación posterior muestra que la variable no está configurada y el directorio no ha cambiado. ¿Qué sucedió? Los cambios se realizaron en un nuevo caparazón. La actual shell generó un nuevo shell para ejecutar el script. El script se ejecuta en el nuevo shell y todos los cambios en el entorno surten efecto en el nuevo shell. Una vez que se completa el script, se destruye el nuevo shell. Todos los cambios en el entorno en el nuevo shell se destruyen con el nuevo shell. Solo el texto de salida se imprime en el shell actual.

Ahora fuente el archivo:

$ source myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir

Comprueba el entorno de nuevo:

$ env | grep FOO
FOO=foo
$ echo $PWD
/home/lesmana/somedir

La variable FOO está configurada y el directorio de trabajo ha cambiado.

Obtener el script no crea un nuevo shell. Todos los comandos se ejecutan en el shell actual y los cambios en el entorno surten efecto en el shell actual.

Tenga en cuenta que en este ejemplo simple, el resultado de la ejecución es el mismo que el de la secuencia de comandos. Este no es necesariamente siempre el caso.

Otra demostración

Considere seguir el script pid.sh :

#!/bin/sh
echo $$

(la variable especial $$ se expande al PID del proceso de shell en ejecución actual)

Primero imprima el PID del shell actual:

$ echo $$
25009

Fuente del guión:

$ source pid.sh
25009

Ejecute el script, tenga en cuenta el PID:

$ ./pid.sh
25011

Fuente de nuevo:

$ source pid.sh
25009

Ejecutar de nuevo:

$ ./pid.sh
25013

Puede ver que la fuente de la secuencia de comandos se ejecuta en el mismo proceso, mientras que la ejecución de la secuencia de comandos crea un nuevo proceso cada vez. Ese nuevo proceso es el nuevo shell que fue creado para la ejecución del script. Obtener el script no crea un nuevo shell y, por lo tanto, el PID permanece igual.

Resumen

Tanto la fuente como la ejecución del script ejecutarán los comandos en el script línea por línea, como si los hubiera escrito a mano línea por línea.

Las diferencias son:

  • Cuando ejecuta el script que está abriendo un nuevo shell, escriba los comandos en el nuevo shell, copie la salida a su shell actual y luego cierre el nuevo shell. Cualquier cambio en el entorno surtirá efecto solo en el nuevo shell y se perderá una vez que se cierre el nuevo shell.
  • Cuando fuentes el script que está escribiendo los comandos en su actual caparazón. Cualquier cambio en el entorno surtirá efecto y permanecerá en su shell actual.

Use la fuente si desea que el script cambie el entorno en su shell que se está ejecutando actualmente. use ejecutar de lo contrario.

Véase también:

  • https://stackoverflow.com/questions/6331075/por-que-necesita-punto-slash-antes-del-nombre-del-script-para-ejecutarlo-en-bash
  • https://askubuntu.com/questions/182012/hay-una-diferencia-entre-y-la-fuente-en-bash-después-de-todo
  • https://stackoverflow.com/questions/18351198/cuáles-son-los-usos-de-los-comandos-exec-en-shell-scripts

Ejecutar un script lo ejecuta en un proceso secundario separado, es decir, se invoca una instancia separada de shell para procesar el script. Esto significa que cualquier variable de entorno, etc., definida en el script no puede actualizarse en el shell principal (actual).

Obtener un script significa que es analizado y ejecutado por el propio shell actual. Es como si escribiera el contenido del script. Por este motivo, no es necesario que el script que se obtiene sea ejecutable. Pero tiene que ser ejecutable si lo estás ejecutando, por supuesto.

Si tiene argumentos posicionales en el shell actual, no se modifican.

Entonces, si tengo un archivo a.sh que contiene:

echo a $*

y lo hago:

$ set `date`
$ source ./a.sh

Obtengo algo como:

a Fri Dec 11 07:34:17 PST 2009

Considerando que:

$ set `date`
$ ./a.sh

me da:

a

Espero que ayude.


el abastecimiento es esencialmente lo mismo que escribir cada línea del script en el símbolo del sistema, una a la vez...

La ejecución inicia un nuevo proceso y luego ejecuta cada línea del script, solo modificando el entorno actual por lo que devuelve.


Linux
  1. La diferencia entre los operadores Bash [[ Vs [ Vs ( Vs ((?)

  2. ¿Cómo leer todo el script de Shell antes de ejecutarlo?

  3. ¿Cuál es la diferencia entre strtok_r y strtok_s en C?

  4. ¿Cuál es la diferencia entre fsck y e2fsck?

  5. ¿Cuál es la diferencia entre adduser y useradd?

¿Cuál es la diferencia entre InnoDB y MyISAM?

¿Cuál es la diferencia entre Linux y Unix?

¿Cuál es la diferencia entre Shell de inicio de sesión y sin inicio de sesión?

¿Qué es un Hipervisor? ¿Cuál es la diferencia entre el tipo 1 y 2?

¿Cuál es la diferencia entre curl y Wget?

¿Cuál es la diferencia entre unlink y rm?