Das Learning Bash Book erwähnt, dass eine Subshell nur Umgebungsvariablen und Dateideskriptoren usw. erbt und keine Variablen, die nicht exportiert werden:
$ var=15
$ (echo $var)
15
$ ./file # this file include the same command echo $var
$
Wie ich weiß, erstellt die Shell zwei Subshells für ()und für ./file, aber warum ()identifiziert die Subshell in diesem Fall die varVariable, obwohl sie nicht exportiert wird, und in dem ./fileFall, dass sie sie nicht identifiziert hat?
# 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
Ich habe versucht straceherauszufinden, wie dies geschieht, und überraschenderweise festgestellt, dass bash dieselben Argumente für den Klonsystemaufruf verwendet. Dies bedeutet, dass sowohl der gegabelte Prozess ()als ./fileauch der Prozessadressraum des übergeordneten Prozesses identisch sind, also warum ()Ist in diesem Fall die Variable für die Subshell sichtbar und geschieht dies nicht für den ./fileFall, obwohl dieselben Argumente auf dem Klonsystemaufruf basieren?