Книга Learning Bash згадує про те, що субшалл успадкує лише змінні середовища та дескриптори файлів тощо, і що він не буде успадковувати змінні, які не експортуються:
$ var=15
$ (echo $var)
15
$ ./file # this file include the same command echo $var
$
Як я знаю, оболонка створить дві підзаголовки для ()
і для ./file
, але чому у ()
випадку підпакет ідентифікує var
змінну, хоча вона не експортується, а у ./file
випадку, якщо вона її не ідентифікувала?
# 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
Я намагався використати, strace
щоб зрозуміти, як це відбувається, і на диво я виявив, що bash використовуватиме однакові аргументи для виклику системи клонування, тому це означає, що обидва роздвоєні процеси в ()
і ./file
повинні мати однаковий адресний простір батьків, тому чому у ()
випадку, коли змінна видима для підрозділу і те ж саме не відбувається для ./file
випадку, хоча ті ж аргументи базуються на виклику системи клонування?