Estoy ejecutando un ejecutable simple llamado hello
bash. Solicita información al usuario e imprime una respuesta. Lo ejecuto así ./hello
.
Tanto la solicitud como el usuario que escribe su respuesta se llevan a cabo en el shell actual, pero pensé que se suponía que debía ejecutarse en un shell diferente. Supuse esto porque puedes usar la fuente para ejecutar el exe en el shell actual.
¿Alguien puede explicarme cómo funciona esto?
Al intentar investigar esto, a menudo me encuentro con los términos "entorno de shell" y "contexto de shell". ¿Son la misma cosa?
Respuesta1
Puede decir "entorno de shell" sobre el entorno del shell actual, que incluye las variables de entorno actuales. El entorno lo hereda cualquier subproceso iniciado (subshell o no).
El "contexto de shell" es un término que no se usa comúnmente, pero supongo que sería equivalente al "contexto de proceso". En el caso de un script de shell, esto incluiría el entorno de shell, así como las variables de shell actuales, descriptores de archivos (entrada estándar, salida estándar y error estándar, y cualquier otro abierto explícitamente), controladores de señales (instalados con trap
), etc. Si fuera un programa en C, el contexto del proceso se heredaría a través de una llamada a fork()
, pero no a través de una llamada posterior exec()
(solo el entorno sobreviviría a una llamada a exec()
).
Cuando ejecuta su hello
programa, que supongo que es un script de Shell, la entrada y la salida ocurren en el contexto del Shell que está ejecutando el hello
script. Este es "el caparazón actual". El shell en el que usted escribió ./hello
es su shell padre y hello
hereda su entorno.
Internamente, el shell principal realiza una llamada fork()
y exec()
para iniciar el shell que eventualmente ejecutará el hello
script.
El hecho de que el hello
guión indique lo mismoTerminalya que el lugar donde inició el script solo significa que el shell que ejecuta el script es el proceso en primer plano actual allí. El shell principal está esperando a que finalice. Cuando finalice, el shell principal volverá a ser el proceso de primer plano en la terminal.
Cuando inicia el script con source ./hello
o . ./hello
, el script se ejecuta en el mismo contexto que el shell en el que escribió ese comando. Esto significa que puede modificar el contexto y el entorno del shell interactivo. Por ejemplo, puede cambiar el directorio de trabajo actual (cambia el entorno) o instalar un controlador de señales (cambia el contexto), y esos cambios aún estarán "activos" cuando el script termine de ejecutarse.
Si el hello
programa es un binario compilado, heredará el entorno del shell que lo invoca, pero no compartirá su contexto (descriptores de archivos, etc.). En realidad, no se ejecuta en un subshell ya que no es un script de shell. El shell principal pasará a un segundo plano, esperando a que finalice el programa, tal como lo haría con un script de shell. Desde el punto de vista del shell principal, no hay diferencia entre iniciar un binario compilado o un script de shell.
Es posible que un binario compilado no se inicie con source
o .
(punto) ya que el shell no sabe cómo interpretar un archivo binario.
Hay un poco de agitación en esta respuesta, pero creo que es básicamente correcta. Deje un comentario (o edítelo) si es necesario corregir o agregar algo.