¿Es un sub-shell lo mismo que un child-shell?

11

Existen estos dos nombres: un subshell y un shell secundario .

Sí, se iniciará un proceso secundario por cualquiera de estos:

sh -c 'echo "Hello"'
( echo "hello" )
echo "$(echo "hello")
echo "hello" | cat

¿Son todos equivalentes y comparten el mismo nombre? ¿Todos comparten las mismas propiedades?


POSIX tiene esta definición :

Un entorno de ejecución de shell consta de ...

Pero el último párrafo del enlace anterior tiene esto:

Se creará un entorno de subshell como duplicado del entorno de shell, excepto que las trampas de señal que no se ignoran se establecerán en la acción predeterminada.

Y especialmente:

La sustitución de comandos, los comandos que están agrupados entre paréntesis y las listas asincrónicas se ejecutarán en un entorno de subshell. Además, cada comando de una tubería de comandos múltiples se encuentra en un entorno de subshell; ....

El sh -c 'echo "Hello"'no está incluido allí, ¿debería eso llamarse también una subshell?

Gilles 'SO- deja de ser malvado'
fuente

Respuestas:

14

Un subshell duplica el shell existente. Tiene las mismas variables¹, las mismas funciones, las mismas opciones, etc. Bajo el capó, se crea una subshell con la forkllamada al sistema²; el proceso hijo continúa haciendo lo que se espera de él mientras el padre espera (por ejemplo, $(…)) o continúa con su vida (por ejemplo, … &) o de lo contrario hace lo que se espera de él (por ejemplo, … | …).

sh -c …no crea una subshell. Lanza otro programa. Ese programa resulta ser un shell, pero eso es solo una coincidencia. El programa puede incluso ser un shell diferente (por ejemplo, si ejecuta sh -c …desde bash y shes dash), es decir, un programa completamente diferente que tiene similitudes significativas en su comportamiento. Bajo el capó, el lanzamiento de un comando externo ( sho cualquier otro) llama a la forkllamada del sistema y luego a la execvellamada del sistema para reemplazar el programa de shell en el subproceso por otro programa (aquí sh).

¹ Incluyendo $$, pero excluyendo algunas variables específicas de shell como bash y mksh BASHPID.
² Al menos, esa es la implementación tradicional y habitual. Los depósitos pueden optimizar el tenedor si pueden imitar el comportamiento de otra manera.

Páginas de manual relevantes: fork (2) , execve (2) .

Gilles 'SO- deja de ser malvado'
fuente
Gracias. ¿A qué pertenece ejecutar un script bash con bash shebang?
Tim
@Tim Lo mismo que sh -c: es un subproceso que casualmente es un shell.
Gilles 'SO- deja de ser malvado'
(1) "el lanzamiento de un comando externo (sh o cualquier otro) llama a la llamada del sistema fork y luego a la llamada del sistema execve para reemplazar el programa de shell en el subproceso por otro programa (aquí sh)". ¿Es correcto que fork primero cree una subshell y luego execve reemplace la subshell con el programa externo? Entonces, en los dos casos en su respuesta, ¿siempre se crea una subshell? (2) "Un subshell que duplica el shell existente". ¿Qué significa eso?
Tim
(3) en bash -c <command>, después de bifurcar el shell y luego ejecutar bash -c <command>, se crea un shell bash. Entonces, ¿se utiliza la llamada del sistema para ejecutar <command>nuevamente bifurcar el shell bash y ejecutar <command>?
Tim
2
@cuonglm "Child shell" no es un término técnico con un significado específico, a diferencia de "subshell". Si es un shell que es un niño, entonces es un shell hijo, siguiendo las reglas habituales del inglés.
Gilles 'SO- deja de ser malvado'
1

Un entorno de shell secundario no necesita vivir en un proceso separado, solo necesita duplicar el entorno de ejecución actual. En ksh93esto se realiza mediante un virtual sub-shellmecanismo que no llama fork(). Esto hace que ksh93 sea muy rápido en plataformas arcaicas como Win-DOS, ya que Win-DOSes extremadamente lento con la bifurcación.

sh -c cmd Por otro lado, crea un nuevo proceso con el shell predeterminado que no necesita ser el mismo que su shell interactivo actual.

Incluso cuando shsu shell actual sea idéntico, esto no duplica el entorno de ejecución y, por lo tanto, no crea un sub-shell.

astuto
fuente
Entonces, en otros shells excepto ksh93, subshell es un shell hijo ¿verdad?
Cuonglm
No conozco ninguna otra implementación que implemente subcapas virtuales hoy en día.
schily