次のトラップ出力について説明してください。
$ 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
コマンド代替サブシェルがトラップ構成を継承すると主張します(実際にはこれに従わないことを除いて)、動作が異なるのはなぜですか?
答え1
興味深い。これは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を使用してバックグラウンドサブプロセスを管理する方が簡単です。