¿Cómo funciona internamente el exec bash incorporado?

¿Cómo funciona internamente el exec bash incorporado?

Deesteenlace Recibo lo siguiente sobre el comando incorporado exec bash:

Si se proporciona el comando,reemplaza el caparazónsin crear un nuevo proceso.

¿Cómo reemplaza exactamente el caparazón (es decir, cómo funciona internamente)? ¿La exec*()llamada al sistema funciona igual?

Respuesta1

Sí, la execfunción integrada finalmente utiliza una de la exec*()familia de llamadas al sistema. También lo hace la ejecución normal de comandos. Es solo que cuando usas exec, no usa la fork()llamada al sistema primero para crear un nuevo proceso, y el resultado es que el nuevo comando reemplaza el shell.

Respuesta2

Hice una straceen una bashinstancia en ejecución. Luego invoqué el comando exec sleep 100. Ahora mira lo que pasó:

access("/bin/sleep", X_OK)              = 0
...
execve("/bin/sleep", ["sleep", "100"], [/* 14 vars */]) = 0
...
nanosleep({100, 0},
...
exit_group(0)                           = ?

Como puedes ver, sucedió casi igual que cuando llamas de sleepla forma normal. bashcomprueba si X_OKse concede el permiso ejecutable ( ) /bin/sleepcon la access()llamada al sistema. Luego execve()ejecuta el programa señalado por el nombre del archivo. Después de execve()la llamada al sistema, sleeptiene el control sobre el proceso. ¿Son cosas: nanosleep(). También mantiene el mismo pid. Una vez sleepfinalizado el proceso también finaliza. Si sleepni ya bashno está funcionando.

Evidencia:

En otra ventana vi el proceso con ps. Antes de ejecutar el comando se veía así:

$ ps -o stat,pid,cmd -p <pid>
Ss+  10905 -bash

Y mientras corres:

$ ps -o stat,pid,cmd -p <pid>
Ss+  10905 sleep 100

Afer sleepterminó el proceso desaparecido.

¿Qué pasó cuando lo ejecuto normalmente?

access("/bin/sleep", X_OK)              = 0
...
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f6c9fd089d0) = 19261
...
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WSTOPPED|WCONTINUED, NULL) = 19261
...
--- SIGCHLD (Child exited) @ 0 (0) ---

Se verifica el permiso de ejecución. Luego se crea un proceso hijo clone(). La bashinstancia ahora está en el grupo de procesos en segundo plano, sleepestá en el grupo de procesos en primer plano. Y por último, la wait4()llamada espera hasta que finalice el proceso hijo (eso necesita 100 segundos).

información relacionada