Considere esto de la documentación de Bash 'builtin exec:
exec reemplaza el shell sin crear un nuevo proceso
Proporcione un caso de uso / ejemplo práctico. No entiendo cómo tiene sentido.
I googled y encontré sobre I / O redirección . ¿Puedes explicarlo mejor?
bash
shell-script
exec
shell-builtin
Ivanov
fuente
fuente
Respuestas:
exec
a menudo se usa en scripts de shell que actúan principalmente como envoltorios para iniciar otros binarios. Por ejemplo:de modo que una vez que el reiniciador termina de ejecutarse, el binario "real" se hace cargo y ya no queda ningún rastro del script del reiniciador que ocupó temporalmente el mismo espacio en la tabla de proceso. El binario "real" es un hijo directo de lo que sea que lo lanzó en lugar de un nieto.
También menciona la redirección de E / S en su pregunta. Ese es un caso de uso bastante diferente
exec
y no tiene nada que ver con reemplazar el shell con otro proceso. Cuandoexec
no tiene argumentos, así:luego, las redirecciones de E / S en la línea de comando surten efecto en el proceso actual del shell, pero el proceso actual del shell continúa ejecutándose y pasa al siguiente comando en el script.
fuente
exec
le dice al shell que no realice la acción (ejecutar un comando o realizar una redirección) en un proceso secundario, sino en el mismo proceso.He usado un shell
exec
incorporado para obtener un ID de proceso (PID) para un programa Java. Puede haber una forma de obtener PID desde Java ahora, pero hace varios años, no la había. Una vez que un proceso tiene su propio PID, puede escribirlo en un archivo PID (busque/var/run/
los nombres de archivo con un sufijo '.pid') para permitir que los programas de administración conozcan el PID del proceso en ejecución y eviten una segunda instancia del mismo servidor de la ejecución. Funciona algo como esto:El código en el
main()
método de claseStartClass
maneja el análisis de argumentos y puede encontrar su propio ID de proceso.fuente
Para divertirse, ejecute el siguiente programa (traducido al lenguaje de implementación que elija) en segundo plano en un sistema con contabilidad y límites de procesos de usuario.
Ahora que cada espacio en la tabla de proceso que puede usar está lleno de copias de ese programa en ejecución, ¿cómo piensa matarlo? Lanzar kill (1) requiere otra ranura de proceso, que no puede tener. Seguro que sería útil que el shell se reemplazara con el comando kill ...
(Asume que su sistema tiene kill (1) en / bin / kill. "Exec` which kill` -9 -1 "es potencialmente más seguro). Esto envía SIGKILL a cada proceso que pueda.
(Nota: no cierre sesión en su shell de inicio a menos que los límites del proceso siempre permitan un nuevo inicio de sesión en un espacio de proceso para su shell. Esto puede ser un poco más difícil de limpiar si lo hace. Ciertamente no hice esto en el principios de los 90. No.)
fuente
exec
comando que sería útil en esta situación. (2) Esta respuesta es algo arcaica; Elkill
comando ha sido un comando incorporado en bash durante muchos años, en gran parte debido a esta preocupación.exec
, y el hecho de quekill
sea una construcción no tiene nada que ver con laexec
construcción.`which kill`
) tampoco funcionará. (2) Por cierto, el$(…)
formulario se recomienda sobre el`…`
formulario. (3) Pero no hay nada peligroso en adivinar el directorio. Si escribe accidentalmenteexec /binn/kill
, simplemente recibirá un mensaje de error y su shell no desaparecerá. (4) Pero ni siquiera tiene que preocuparse por el directoriokill
en el que seexec
utiliza . Al$PATH
igual que los comandos normales,exec kill …
funciona (suponiendo que tenga/bin
en su ruta de búsqueda).Esto es similar al ejemplo de Bruce de la necesidad de conocer el PID de un proceso:
en el que tu
(
y)
),$$
le dará el PID del shell principal).Esto se ejecutará
long-running-command
, pero solo por un período de tiempo predeterminado y limitado.Esto es un poco frívolo, pero, si decides que quieres ser root (o algún otro usuario) durante el resto de tu sesión de inicio de sesión, podrías hacerlo
exec su
.En realidad, puedo imaginar un escenario en el que esto sería realmente útil. Suponga que ha iniciado sesión en un sistema remoto y, por alguna razón, hay un problema al interrumpir la conexión y comenzar una nueva conexión. Por ejemplo, suponga que el sistema remoto tiene un firewall que sigue un cronograma. Se le permitió conectarse cuando lo hizo, y las conexiones establecidas no se cierran, pero en este momento, no se aceptan nuevas conexiones.
Has hecho lo que querías hacer y estás listo para cerrar sesión. Su amigo Bob está en la habitación con usted y quiere trabajar en el sistema remoto, pero no podrá conectarse. Entonces, escribe
exec su - bob
y, cuando aparece el mensaje de contraseña, dele la estación de trabajo a él. Ahora no hay ningún proceso con su UID (a menos que haya ejecutado algo en segundo plano), por lo que Bob no podrá jugar con sus archivos. Él se habrá hecho cargo de su conexión (con su consentimiento y cooperación).Notas:
su
.who
probablemente aún muestre su nombre. Es concebible que algún programa (mal escrito) lo use para pensar que Bob eres tú y darle acceso a tus recursos.fuente
(a;b)
ya es lo mismo(a;exec b)
que los shells que optimizan la bifurcación para el último comando en un subshell. Las únicas excepciones parecen serbash
ymksh
. Usarexec
ayuda para garantizarlo.