Eu fiz um strace
em uma instância bash
em execução. Então invoquei o comando exec sleep 100
. Agora veja o que aconteceu:
access("/bin/sleep", X_OK) = 0
...
execve("/bin/sleep", ["sleep", "100"], [/* 14 vars */]) = 0
...
nanosleep({100, 0},
...
exit_group(0) = ?
Então, você pode ver, aconteceu quase como quando você chama sleep
do modo normal. bash
verifica se a permissão executável ( X_OK
) é concedida para /bin/sleep
com a chamada do sistema access()
. Então execve()
executa o programa apontado pelo nome do arquivo. Depois de execve()
syscall, sleep
tem o controle sobre o processo. Faz as coisas: nanosleep()
. Ele também mostra o mesmo pid. Depois que sleep
terminou, o processo termina também. Se sleep
nem bash
não está mais sendo executado.
Evidências:
Em outra janela, assisti ao processo com ps
. Antes de executar o comando, ficou assim:
$ ps -o stat,pid,cmd -p <pid>
Ss+ 10905 -bash
E enquanto corre:
$ ps -o stat,pid,cmd -p <pid>
Ss+ 10905 sleep 100
Afer sleep
terminou o processo desapareceu.
O que aconteceu quando eu corri 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) ---
A permissão de execução está marcada. Em seguida, um processo filho é criado clone()
. A instância bash
está agora no grupo de processos em segundo plano, sleep
está no grupo de processos em primeiro plano. E, por fim, a chamada wait4()
aguarda até que o processo filho seja finalizado (que precisa de 100 segundos).