[Linuxtrent] Re: bash find e source

  • From: Daniele Pizzolli <ors@xxxxxxxx>
  • To: linuxtrent@xxxxxxxxxxxxx
  • Date: Tue, 08 May 2012 21:46:06 +0200

On 05/08/2012 07:38 PM, Mauro Colorio wrote:

[]

ma mi chiedevo perchè non lancasse il source che non è un binario ma
un built-in della bash
e credo sia proprio questo il motivo ma ..perchè? :)

builtin vs comandi /reali/ è sempre un buon tema al corso shell...
e in effetti a prima vista è difficile capire cosa è un builtin
e come funziona il source, che nello standard posix è il punto: .
source è un bashism...

La /dimostrazione più concisa/ usando un po’ di introspezione, che mi
viene in mente è:

$ PATH=/bin:/usr/bin/ strace -f -e trace=process find /var/local -exec ls -a {} 
\;
execve("/usr/bin/find", ["find", "/var/local", "-exec", "ls", "-a", "{}", ";"], 
[/* 44 vars */]) = 0
clone(Process 16566 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, 
child_tidptr=0xb776d728) = 16566
[pid 16565] waitpid(16566, Process 16565 suspended
 <unfinished ...>
[pid 16566] execve("/bin/ls", ["ls", "-a", "/var/local"], [/* 44 vars */]) = 0
.  ..
[pid 16566] exit_group(0)               = ?
Process 16565 resumed
Process 16566 detached
<... waitpid resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0) = 16566
--- SIGCHLD (Child exited) @ 0 (0) ---
exit_group(0)                           = ?
$ apropos -e execve
execve (2)           - execute program
$ echo "ls -a /var/local" > /var/tmp/source_me
ors@gemini:~$ strace -f -e trace=process /bin/sh -c ". /var/tmp/source_me"
execve("/bin/sh", ["/bin/sh", "-c", ". /var/tmp/source_me"], [/* 44 vars */]) = 0
clone(Process 2208 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, 
child_tidptr=0xb7724938) = 2208
[pid  2207] wait4(-1, Process 2207 suspended
 <unfinished ...>
[pid  2208] execve("/bin/ls", ["ls", "-a", "/var/local"], [/* 44 vars */]) = 0
.  ..
[pid  2208] exit_group(0)               = ?
Process 2207 resumed
Process 2208 detached
<... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 2208
--- SIGCHLD (Child exited) @ 0 (0) ---
exit_group(0)                           = ?


Ovvero find fa il fork (clone è un po’ più di basso livello di fork)
che chiama l’argomento di exec con usando execve, che si aspetta di
eseguire un programma.

Quando si esegue il . invece non c’è nessun fork, e non ci deve
essere se si vuole che il file del quale si è fatto il source modifichi
l’ambiente della shell. Anche qui il fork viene fatto sul ls
e non sul ". /var/tmp/source_me".

Con piccoli aggiustamenti si può provare:
strace -f -e trace=process /bin/sh -c "/var/tmp/source_me"
find /var/local -exec . {} \;
...


Buona serata,
Daniele
--
Per iscriversi  (o disiscriversi), basta spedire un  messaggio con OGGETTO
"subscribe" (o "unsubscribe") a mailto:linuxtrent-request@xxxxxxxxxxxxx


Other related posts: