3

このスクリプトにはスクリプトtrap.shがあります

#!/bin/bash
trap "echo trapped" EXIT
exit 0

およびtest.sh。test.sh が似ている場合

#!/bin/bash
. trap.sh

また

#!/bin/bash
./trap.sh | :

トラップが効く

しかし、test.shが似ている場合

#!/bin/bash
. trap.sh | :

トラップは機能しませんでした。

これがなぜなのか知っている人はいますか?

4

3 に答える 3

1

オプションtrap.shを入れるように修正しました。xtrace

#!/bin/bash
set -x
trap 'echo trapped' EXIT
exit 0

trap.shスクリプトとして実行すると生成されます

~ $ ./trap.sh | 猫 + トラップ「エコー トラップ」 EXIT + 終了 0 + エコー トラップ トラップ

ただし、最初に調達すると

~ $ . trap.sh | cat
++ trap 'echo trapped' EXIT
++ exit 0

これは、trapがより深いサブシェルで実行され (理由はわかりません)、トラップ自体は決して実行されないことを示しています (2 番目の実験でtouchは、単にエコーするのではなく、トラップにファイルを ing することで確認しました。継承される標準出力の問題でした; ファイルはまったく変更されませんでした)。

私の推測では、man ページのコマンドの説明からの次の文に基づいてEXIT、コマンドが実行される前に信号が無視されていると思います。sourcetrap

シェルへのエントリ時に無視されたシグナルは、トラップまたはリセットできません。

その結果、trapコマンドは実行されますが、トラップ自体は登録されないため、起動しません。

于 2013-10-15T14:10:24.077 に答える
1

テスト コマンドを. trap.sh|cat( からの標準出力をtrap.shで表示できませんでした) に変更することをお勧めします:。しかし、それでも出力がないので、その通りです。トラップは機能しませんでした。これは bash のバグである必要があり、メンテナに報告する必要があります。

興味深いことに、echo $$trap.sh スクリプト内から見ると、パイプライン全体を実行するのと同じシェルによって実行されていることがわかります。これは. trap.sh|cat、マニュアルの記述と矛盾しています。パイプライン内の各コマンドは、個別のプロセスとして実行されます (つまり、サブシェル)。 これは誤りでした。コメントを参照してください。おそらくこれは、サブシェルの作成を最小限に抑えるための最適化に関連していますが、それは単なる推測です。

于 2013-10-15T11:33:27.287 に答える
0

パイプの左側のコマンドは、サブシェルで実行されます。

exit | grep

exit sigtrap がサブシェルに伝播されていないようです。

trap 'echo T >&2' EXIT ; (exit)    # Nothing.
于 2013-07-19T08:21:52.457 に答える