入力リダイレクトサブシェルにパイプが使用されている場合、Ctrl-cはシェルを終了します。

入力リダイレクトサブシェルにパイプが使用されている場合、Ctrl-cはシェルを終了します。

次のコマンドを実行すると:

cat <(echo 1 | pv) | pv
cat <(echo 1 | pv) | less
cat <(echo 1 | pv) | cat

コマンドが永久に実行されるようです。 (SIGINT)と入力すると、^C実行されたコマンドだけでなく、シェル全体が終了します。なぜですか?


ps xf他のシェルの最小関連出力cat <(pv) | less:

Ss  /bin/bash
S+   \_ cat /dev/fd/XX
S    |   \_ /bin/bash
T    |       \_ pv
S+   \_ less

次のファイル記述子を開きます。

強く打つ

0 -> /dev/pts/YY
1 -> /dev/pts/YY
2 -> /dev/pts/YY
255 -> /dev/pts/YY

猫/開発者/fd/ZZ

0 -> /dev/pts/YY
1 -> pipe:[RRRRRRRR]
2 -> /dev/pts/YY
3 -> pipe:[QQQQQQQQ]
ZZ -> pipe:[QQQQQQQQ]

強く打つ

0 -> /dev/pts/YY
1 -> pipe:[QQQQQQQQ]
2 -> /dev/pts/YY
255 -> /dev/pts/YY

PV

0 -> /dev/pts/YY
1 -> pipe:[QQQQQQQQ]
2 -> /dev/pts/YY

少ない

0 -> pipe:[RRRRRRRR]
1 -> /dev/pts/YY
2 -> /dev/pts/YY
3 -> /dev/tty

cat <(echo 1 | pv) | less元の例を使用すると(これはbash組み込みではなく他のプログラムでも発生します。例:echodd if=/dev/zero bs=1 count=1

Ss   /bin/bash
S+    \_ cat /dev/fd/63
S     |   \_ /bin/bash
T     |       \_ pv
S+    \_ less

強く打つ

0 -> /dev/pts/18
1 -> /dev/pts/18
2 -> /dev/pts/18
255 -> /dev/pts/18

猫/開発者/fd/63

0 -> /dev/pts/18
1 -> pipe:[36932796]
2 -> /dev/pts/18
3 -> pipe:[36929317]
63 -> pipe:[36929317]

強く打つ

0 -> /dev/pts/18
1 -> pipe:[36929317]
2 -> /dev/pts/18
255 -> /dev/pts/18

PV

0 -> pipe:[36930391]
1 -> pipe:[36929317]
2 -> /dev/pts/18

少ない

0 -> pipe:[36932796]
1 -> /dev/pts/18
2 -> /dev/pts/18
3 -> /dev/tty

ベストアンサー1

これは<(、プロセスに)適切なジョブ制御がないために発生します。つまり、フォークされて忘れてしまいます。ほとんどの場合、これは問題ではありません。なぜならほぼプロセスは作成されるとすぐに別々のプロセスグループとバックグラウンドに配置されます。 ~のため即時シェルはこのプロセスの入出力を開く必要がありますが、これはttyの前景プロセスグループであるため、SIGINTに対して脆弱です。インタラクティブシェルが通常行うようにキャプチャまたは無視されない限り。

しかし問題はこんな感じです。パイプラインがデッドロックに陥りました。親プロセスがプロセスの出力を開こうとすると、パイプはブロックされます。プロセスグループと他のすべてのグループを変更する機会はありません。CTRL+Cフォアグラウンドグループが終了し、SIGINTが送信されます。前景グループが終了し、親グループがまだパイプによってブロックされており、制御権を再取得できない場合は、自宅に誰もいないため、ターミナルからHUPを送信します。カブーム

別のパイプを開くには、まず開くパイプごとに作成者とリーダーが必要です。

おすすめ記事