GNU/Linux >> Tutoriales Linux >  >> Linux

¿Las variables que no son de entorno se pasan al subshell invocado por sustitución de comando?

El manual de bash dice:

La sustitución de comandos, los comandos agrupados entre paréntesis y los comandos asincrónicos se invocan en un entorno de subshell que es un duplicado del entorno de shell,
excepto que las trampas capturadas por el shell se restablecen a los valores que el shell heredó de su padre en invocación.

En este ejemplo, b no es una variable de entorno, por lo que b no existe en la subcapa creada por la sustitución de comandos. Entonces, ¿por qué c asignó el valor de b por sustitución de mando? ¿Es porque la expansión del parámetro ocurre para $b? en el proceso de shell antes de crear un subshell para ejecutar echo 1 ?

$ b=1
$ c=$(echo $b)
$ echo $c
1

Respuesta aceptada:

No, la subcapa se creó primero.

Un entorno de ejecución de shell contiene parámetros de shell establecidos por asignaciones de variables y variables de entorno. Se creó un entorno de subshell mediante la duplicación del entorno de shell, por lo que contiene todas las variables del entorno de shell actual.

Ver el ejemplo:

$ b=1
$ c=$(b=2; echo "$b")
$ echo "$c"
2

La salida es 2 en lugar de 1 .

Un entorno de subshell creado mediante la sustitución de comandos es diferente de un entorno de shell creado llamando al ejecutable de shell.

Cuando llamas al shell como:

$ bash -c :

el shell actual usó execve() para crear un nuevo proceso de shell, algo así como:

execve("/bin/bash", ["bash", "-c", ":"], [/* 64 vars */]) = 0

el último argumento pasado a execve contiene todas las variables de entorno.

Es por eso que necesita exportar las variables para enviarlas a las variables de entorno, que se incluirán en los comandos ejecutados posteriormente:

$ a=; export a
$ strace -e execve bash -c :
execve("/bin/bash", ["bash", "-c", ":"], [/* 65 vars */]) = 0
+++ exited with 0 +++

Observe que las variables de entorno cambian de 64 a 65. Y las variables que no se exportan no se pasarán al nuevo entorno de shell:

$ a=; b=; export a
$ strace -e execve bash -c :
execve("/bin/bash", ["bash", "-c", ":"], [/* 65 vars */]) = 0
+++ exited with 0 +++

Observe que las variables de entorno siguen siendo 65.

En la sustitución de comandos, el shell usó fork() para crear un nuevo proceso de shell, que simplemente copió el entorno de shell actual, que contiene tanto el conjunto de variables como las variables de entorno.


Linux
  1. Alias ​​de línea de comandos en el shell de Linux

  2. ¿Los paréntesis realmente ponen el comando en una subcapa?

  3. ¿Cuál es la diferencia de obtener salida de comando usando `command` y $(command) en Shell?

  4. Linux:¿las variables de entorno son visibles para los usuarios sin privilegios en Linux?

  5. ¿Cómo se interpretan los paréntesis en la línea de comandos?

¿Cuáles son los parámetros/variables especiales de Shell (bash)?

¿Cuáles son los diferentes tipos de shells en Linux?

Comprender las variables en Bash Shell en Linux

useradd vs adduser:¿Cuáles son las diferencias?

¿Cuál es el alcance de las variables de shell exportadas en Unix?

¿Ocultar la salida de un comando de shell solo en caso de éxito?