Subshell padrão vs subshell de substituição de comando

8

Por favor, explique estas saídas de interceptação:

$ line(){ echo -------------; echo $BASHPID; }
$ trap 'echo bye' EXIT; trap -p; line; (trap -p; line); echo "$(trap -p; line)"

trap -- 'echo bye' EXIT
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6176
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6178
trap -- 'echo bye' EXIT
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6180

Por que o subshell de substituição de comando se comporta de maneira diferente no sentido em que afirma ter herdado as disposições de interceptação (exceto que na verdade não as segue)?

PSkocik
fonte

Respostas:

2

Interessante. Esse parece ser um comportamento específico do Bash.

Eu tentei três outros shells compatíveis com POSIX (zsh, dash, busybox) e, em todos eles, echo "$(trap)"deram o mesmo resultado que (trap): um subshell é executado e o subshell não mostra uma EXITarmadilha.

(Observe que trap -pé específico do Bash e, sem parâmetros extras, ele faz o mesmo que trapsem parâmetros).

O comportamento do Bash é potencialmente útil : significa que você pode escrever a="$(trap)"para capturar as configurações de interceptação do shell pai, que são mais prováveis ​​de serem interessantes.

No entanto, se você definir ou limpar uma armadilha na subshell, em seguida, ele irá listar armadilhas do subshell em vez do pai de:

$ trap 'echo bye' EXIT
$ echo "$(trap TERM; trap)"  # explicitly clear TERM, but leave EXIT alone
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU

Então, eles também abordaram o caso raro em que você está interessado nas armadilhas do subshell.

Em geral, notei que os desenvolvedores do Bash parecem ter se esforçado mais para fazer com que o manuseio de subconjuntos funcione bem. Também é muito mais fácil gerenciar subprocessos em segundo plano com o Bash do que com os shells POSIX mais mínimos.

Jander
fonte