()
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 foo
ainda sai apenas da subcamada.
No entanto, diferentes cartuchos se comportam de maneira diferente a esse respeito. Por exemplo,
bash
coloca todos os componentes do pipeline em subshells separados (a menos que você use a opçãolastpipe
em invocações onde o controle de job não está habilitado), mas AT & Tksh
ezsh
executam a última parte dentro do shell atual (ambos os comportamentos são permitidos pelo POSIX). Assimexit | exit | exit
basicamente não faz nada no bash, mas sai do zsh por causa do último
exit
. -
coproc exit
também executaexit
em uma subshell.