GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cuál es la diferencia entre usar `sh` y `source`?

La principal diferencia es que se ejecutan en un proceso diferente.

Así que si source un archivo foo que hace un cd , el shell de abastecimiento (por ejemplo, su shell interactivo en la terminal) se ve afectado (y su directorio actual cambiará)

Si ejecuta sh foo el cd no afecta el shell de abastecimiento, solo el sh recién creado proceso ejecutando foo

Lea la Guía avanzada de secuencias de comandos de Bash.


Como han mencionado otros, cuando ejecutas sh test.sh , cualquier cambio que test.sh hace a su entorno de shell no persistirá después de que el proceso haya finalizado.

Sin embargo, también tenga en cuenta que cualquier elemento de su entorno que no se exporte (por ejemplo, variables, alias y funciones de shell) no estará disponible para el código en test.sh cuando se ejecuta como un subproceso (es decir, con sh test.sh ).

Por ejemplo:

$ cat > test.sh
echo $foo
$ foo=bar
$ sh test.sh
$ . test.sh
bar

Ejemplo 2:

[email protected]:~$ cat test.sh
#!/bin/sh
cd /etc
[email protected]:~$ sh test.sh 
[email protected]:~$ pwd
/home/savoury
[email protected]:~$ source test.sh 
[email protected]:/etc$ pwd
/etc
[email protected]:/etc$ 

Cuando llamas al source o . (uno es un alias del otro. source cmd no POSIX - una especie de bashism ), carga y ejecuta un script de shell en el actual proceso de shell . Entonces puedes

  • leer las variables establecidas en el script de origen,
  • usar funciones definidas dentro de él.
  • e incluso ejecutar bifurcaciones y/o subprocesos si el script hace esto.

Cuando llamas al sh , inicias una bifurcación (subproceso o hijo ) que ejecuta una nueva sesión de /bin/sh (que suele ser un enlace simbólico a bash ). En este caso, las variables de entorno establecidas por el subíndice se descartarían cuando el subíndice termine.

Precaución :sh podría ser un enlace simbólico a otro concha.

Muestra práctica

Por ejemplo, si desea cambiar el directorio de trabajo actual de una manera específica, no podrías hacer

$ cat <<eof >myCd2Doc.sh
#!/bin/sh
cd /usr/share/doc
eof

$ chmod +x myCd2Doc.sh

Esto no hará lo que esperas:

$ cd /tmp
$ pwd
/tmp
$ ~/myCd2Doc.sh
$ pwd
/tmp

porque directorio de trabajo actual es parte del entorno y myCd2Doc.sh se ejecutaría en una subcapa .

Pero:

$ cat >myCd2Doc.source <<eof
# Shell source file
myCd2Doc() {
    cd /usr/share/doc
}
eof

$ . myCd2Doc.source
$ cd /tmp
$ pwd
/tmp
$ myCd2Doc
$ pwd
/usr/share/doc

Echa un vistazo a mycd ¡¡función!! (Con bash completado basado en Asociative Array ).

Nivel de ejecución $SHLVL

$ cd /tmp
printf %b '\43\41/bin/bash\necho This is level \44SHLVL.\n' >qlvl.sh

$ bash qlvl.sh 
This is level 2.

$ source qlvl.sh 
This is level 1.

Recursividad (cuando un script se ejecuta desde sí mismo)

$ cat <<eoqlvl2 >qlvl2.sh 
#!/bin/bash

export startLevel recursionLimit=5
echo This is level $SHLVL started:${startLevel:=$SHLVL}.
(( SHLVL < recursionLimit )) && ./qlvl2.sh
eoqlvl2
$ chmod +x qlvl2.sh

$ ./qlvl2.sh 
This is level 2 started:2.
This is level 3 started:2.
This is level 4 started:2.
This is level 5 started:2.

$ source qlv2.sh 
This is level 1 started:1.
This is level 2 started:1.
This is level 3 started:1.
This is level 4 started:1.
This is level 5 started:1.

Un poco más

$ sed '$a ps --sid $SID fw' qlvl.sh >qlvl3.sh
$ chmod +x qlvl3.sh 
$ export SID
$ read SID < <(ps ho sid $$)
$ echo $SID $$
8983 8983

( PID actual ($$ ==Id. de proceso ) son el mismo identificador que SID (ID de sesión ). No siempre es cierto.)

$ ./qlvl3.sh 
This is level 2.
  PID TTY      STAT   TIME COMMAND
 8983 pts/10   Ss     0:00 /bin/bash
10266 pts/10   S+     0:00  \_ /bin/bash ./qlvl3.sh
10267 pts/10   R+     0:00      \_ ps --sid 8983 fw

$ . qlvl3.sh 
This is level 1.
  PID TTY      STAT   TIME COMMAND
 8983 pts/10   Ss     0:00 /bin/bash
10428 pts/10   R+     0:00  \_ ps --sid 8983 fw

Punto . es un alias de source . Entonces, la única diferencia entre dos comandos es slash reemplazado por space .

Y una final prueba:

$ printf %b '\43\41/bin/bash\necho Ending this.\nsle' \
    'ep 1;exit 0\n' >finalTest.sh

$ bash finalTest.sh 
Ending this.

$ source finalTest.sh
Ending this.

... Puede notar un diferente comportamiento entre las dos sintaxis.;-)


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

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

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

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

  5. ¿Cuál es la diferencia entre usar upstream y location para php-fpm?

¿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?

¿Cuál es la diferencia entre el comando apt y apt-get?

¿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 ruta y ruta ip?