No Ubuntu, executo date
diretamente em um shell bash interativo cujo pid é 6913.
$ date
Wed Mar 2 23:57:44 EST 2016
Ao mesmo tempo, eu rastreio o shell bash 6913 de outro shell bash interativo usando strace
:
$ sudo strace -f -e trace=process -p 6913
Process 6913 attached
clone(Process 9098 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,
child_tidptr=0x7f457c05ca10) = 9098
[pid 6913] wait4(-1, <unfinished ...>
[pid 9098] execve("/bin/date", ["date"], [/* 66 vars */]) = 0
[pid 9098] arch_prctl(ARCH_SET_FS, 0x7f40d6a4f740) = 0
[pid 9098] exit_group(0) = ?
[pid 9098] +++ exited with 0 +++
<... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WSTOPPED|WCONTINUED, NULL) = 9098
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=9098, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, 0x7ffea6781518, WNOHANG|WSTOPPED|WCONTINUED, NULL) = -1 ECHILD (No child processes)
clone(Process 9099 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f457c05ca10) = 9099
[pid 9099] clone(Process 9100 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f457c05ca10) = 9100
[pid 9099] wait4(-1, <unfinished ...>
[pid 9100] execve("/bin/sed", ["sed", "s:\([^/]\)[^/]*/:\1/:g"], [/* 66 vars */]) = 0
[pid 9100] arch_prctl(ARCH_SET_FS, 0x7f998bb03840) = 0
[pid 9100] exit_group(0) = ?
[pid 9100] +++ exited with 0 +++
[pid 9099] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 9100
[pid 9099] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=9100, si_status=0, si_utime=0, si_stime=0} ---
[pid 9099] wait4(-1, 0x7ffea6780c58, WNOHANG, NULL) = -1 ECHILD (No child processes)
[pid 9099] exit_group(0) = ?
[pid 9099] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=9099, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG|WSTOPPED|WCONTINUED, NULL) = 9099
wait4(-1, 0x7ffea6780f18, WNOHANG|WSTOPPED|WCONTINUED, NULL) = -1 ECHILD (No child processes)
Parece-me que a saída pode ser dividida em duas partes:
-
Primeiro o shell do bash 6913 clone()
para criar um subprocesso
9098 e, em seguida, o subprocesso 9098 execve()
date
e sai.
-
Depois disso, o shell bash 6913 clone()
cria uma
subprocesso 9099, em seguida, o subprocesso 9099 clone()
próprio para criar
um sub-processo 9100 e, em seguida, o subsubprocesso 9100 execve()
sed
. A minha pergunta é sobre esta segunda parte:
-
Os últimos dois clone()
e o último execve()
pertencem à ação que manipula o SIGCHLD recebido pelo bash shell 6913?
O que a ação faz?
-
Por que processar 9100 execve()
sed
? O que o sed
faz aqui?
-
Por que o processo 9099 não é o processo que execve()
sed
? Por que 9099 clone()
para criar 9100 e, em seguida, 9100 execve()
sed
? Em outras palavras, por que precisamos de dois clones sequenciais 9099 e 9100, em vez de apenas um clone 9099?
Para responder ao comentário:
$ echo $PROMPT_COMMAND
pwd2=$(sed "s:\([^/]\)[^/]*/:/:g" <<<$PWD)
$ echo $PS1
\u@\h:$pwd2\$
Depois de executar unset PROMPT_COMMAND
no shel 6913, a saída de rastreio é
$ sudo strace -f -e trace=process -p 6913
[sudo] password for t:
Process 6913 attached
clone(Process 12918 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f457c05ca10) = 12918
[pid 6913] wait4(-1, <unfinished ...>
[pid 12918] execve("/bin/date", ["date"], [/* 66 vars */]) = 0
[pid 12918] arch_prctl(ARCH_SET_FS, 0x7ff00c632740) = 0
[pid 12918] exit_group(0) = ?
[pid 12918] +++ exited with 0 +++
<... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WSTOPPED|WCONTINUED, NULL) = 12918
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=12918, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, 0x7ffea6781518, WNOHANG|WSTOPPED|WCONTINUED, NULL) = -1 ECHILD (No child processes)
Portanto, as duas primeiras perguntas acima são agora respondidas. Ainda não tenho certeza sobre a terceira questão.