() executa comandos no subshell, portanto, exit você está saindo do subshell e retornando ao shell pai. Use chaves {} se você quiser executar comandos no shell atual.
Do manual do bash:
(list) list is executed in a subshell environment. Variable assignments and builtin commands that affect the shell's environment do not remain in effect after the command completes. The return status is the exit status of list.
{ list; } list is simply executed in the current shell environment. list must be terminated with a newline or semicolon. This is known as a group command. The return status is the exit status of list. Note that unlike the metacharacters ( and ), { and } are reserved words and must occur where a reserved word is permitted to be recognized. Since they do not cause a word break, they must be separated from list by whitespace or another shell metacharacter.
Vale ressaltar que a sintaxe do shell é bastante consistente e o subshell também participa das outras construções de () , como a substituição de comando (também com a sintaxe de '..' do estilo antigo) ou substituição de processo. sair do shell atual:
echo $(exit)
cat <(exit)
Embora seja óbvio que as subshells estão envolvidas quando os comandos são colocados explicitamente dentro de () , o fato menos visível é que eles também são gerados nessas outras estruturas:
-
comando iniciado em segundo plano
exit &não sai do shell atual porque (após
man bash)If a command is terminated by the control operator &, the shell executes the command in the background in a subshell. The shell does not wait for the command to finish, and the return status is 0.
-
o pipeline
exit | echo fooainda sai apenas da subcamada.
No entanto, diferentes cartuchos se comportam de maneira diferente a esse respeito. Por exemplo,
bashcoloca todos os componentes do pipeline em subshells separados (a menos que você use a opçãolastpipeem invocações onde o controle de job não está habilitado), mas AT & Tkshezshexecutam a última parte dentro do shell atual (ambos os comportamentos são permitidos pelo POSIX). Assimexit | exit | exitbasicamente não faz nada no bash, mas sai do zsh por causa do último
exit. -
coproc exittambém executaexitem uma subshell.