Você ou o livro está confundindo um subshell com um subprocesso que é um shell.
Algumas construções de shell fazem com que o shell bifurque o processo filho. No Linux, fork é um caso especial da chamada de sistema clone mais geral, que você observou no strace log. O filho executa uma parte do script de shell. O processo filho é chamado de subshell . A construção mais direta é command1 & : command1 é executada em um subshell e os comandos subseqüentes são executados no shell pai. Outras construções que criam uma subshell incluem a substituição de comando $(command2) e pipes command3 | command4 ( command3 é executado em uma subshell, command4 é executado em uma subshell na maioria das shells, mas não em ksh ou zsh).
Um subshell é uma cópia do processo pai, portanto, ele possui não apenas as mesmas variáveis de ambiente, mas também as mesmas definições internas: variáveis (incluindo $$ , o ID do processo original do shell), funções, aliases, opções, etc. Antes de executar o código no subshell, o bash define a variável BASHPID como o ID do processo filho.
Quando você executa ./file , isso executa um comando externo. Primeiro, o shell bifurca um processo filho; então este processo filho executa (com a chamada do sistema execve ) o arquivo executável ./file . Um processo filho herda os atributos de processo de seus pais: ambiente, diretório atual, etc. Aspectos internos do aplicativo são perdidos na chamada execve : variáveis não exportadas, funções, etc. são noções básicas que o kernel não sabe sobre, e eles são perdidos quando o bash executa outro programa. Mesmo que esse outro programa seja um script bash, ele é executado por uma nova instância do bash que não sabe ou não se importa que o processo pai também seja uma instância do bash. Assim, uma variável do shell (variável não exportada) não sobrevive a execve .