O Learning Bash Book menciona que um subshell herdará apenas variáveis de ambiente e descritores de arquivos etc., e que não herdará variáveis que não são exportadas:
$ var=15
$ (echo $var)
15
$ ./file # this file include the same command echo $var
$
Como eu sei, o shell criará dois subshells para ()e para ./file, mas por que no ()caso o subshell identifica a varvariável, embora não seja exportada e, no ./filecaso, não a identificou?
# 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
Tentei usar stracepara descobrir como isso acontece e, surpreendentemente, descobri que o bash usará os mesmos argumentos para a chamada do sistema clone, então isso significa que o processo bifurcado ()e ./fileo mesmo devem ter o mesmo espaço de endereço do pai, então por que no ()caso, a variável é visível para o subshell e o mesmo não ocorre para o ./filecaso, embora os mesmos argumentos sejam baseados na chamada do sistema clone?