web-dev-qa-db-ja.com

標準サブシェルとコマンド置換サブシェル

これらのトラップ出力について説明してください。

$ 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

コマンド置換サブシェルがトラップの性質を継承したと主張するという点で、なぜ異なる動作をするのですか(実際にはそれらに従わないことを除いて)?

8
PSkocik

面白い。これはBash固有の動作のようです。

他の3つのPOSIX互換シェル(zsh、dash、busybox)を試しましたが、それらすべてでecho "$(trap)"は_(trap)_と同じ結果になりました。サブシェルが実行され、サブシェルが表示されませんEXITトラップ。

(_trap -p_はBashに固有であり、追加のパラメーターがない場合は、パラメーターがない場合のtrapと同じことを行うことに注意してください。)

Bashの動作は潜在的に有用です:これは、a="$(trap)"を記述して、より興味深い可能性が高い親シェルのトラップ設定をキャプチャできることを意味します。

ただし、サブシェルでトラップを設定またはクリアすると、親のトラップではなく、サブシェルのトラップがリストされます

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

そのため、サブシェルのトラップに関心があるというまれなケースについても説明しました。

一般に、Bash開発者は、サブシェル処理を適切に機能させるために特別な努力を払っているように見えることに気づきました。また、最小限のPOSIXシェルを使用するよりも、Bashを使用してバックグラウンドサブプロセスを管理する方がはるかに簡単です。

2
Jander