Le Learning Bash Book mentionne qu'un sous-shell héritera uniquement des variables d'environnement et des descripteurs de fichiers, etc., et qu'il n'héritera pas des variables qui ne sont pas exportées:
$ var=15
$ (echo $var)
15
$ ./file # this file include the same command echo $var
$
Comme je sais, le shell créera deux sous-coquilles pour ()
et pour ./file
, mais pourquoi dans le ()
cas la sous-coquille identifie-t-elle la var
variable bien qu'elle ne soit pas exportée et dans le ./file
cas où elle ne l'a pas identifiée?
# Strace for ()
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25617
# Strace for ./file
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25631
J'ai essayé d'utiliser strace
pour comprendre comment cela se produit et, de façon surprenante, j'ai trouvé que bash utilisera les mêmes arguments pour l'appel système clone, ce qui signifie que le processus forké ()
et ./file
devrait avoir le même espace d'adressage de processus du parent, alors pourquoi dans le ()
cas, la variable est visible pour le sous-shell et la même chose ne se produit pas pour le ./file
cas, bien que les mêmes arguments soient basés sur l'appel système du clone?