@Bakuriu がコメントで指摘しているように、これは基本的にBASH と同じ問題です。入力中に Ctrl+C を押す と、現在の端末が中断されます。 、端末のクリーンアップをうまく処理しているようです。この点で bash が壊れているように見える理由についての回答に興味があります。
そのスクリプトによって開始されたサブプロセスの出力をログに記録するための Python スクリプトがあります。サブプロセスがたまたま bash スクリプトであり、ある時点でread -s
ビルトイン (入力された-s
文字のエコーを防ぐ がキー) を呼び出してユーザー入力を読み取り、ユーザーがスクリプトを中断した場合 (つまり、Ctrl-C によって)、その後、bash は引き続き入力を受け付けますが、出力を tty に復元できません。
これを簡単な例に絞り込みました。
$ cat test.py
#!/usr/bin/python
import subprocess as sp
p = sp.Popen(['bash', '-c', 'read -s foo; echo $foo'])
p.wait()
実行./test.py
すると、何らかの入力を待ちます。なんらかの入力をして Enter キーを押すと、スクリプトは期待どおりに入力を返し、エコーします。問題はありません。ただし、すぐに「Ctrl-C」を押すと、Python は のトレースバックを表示してKeyboardInterrupt
から、bash プロンプトに戻ります。ただし、入力したものは端末に表示されません。ただし、入力reset<enter>
すると端末が正常にリセットされます。
ここで何が起こっているのか正確にはわかりません。
更新: Python を使用せずにこれを再現することもできました。strace で bash を実行して、何が起こっているのかを収集できるかどうかを確認しようとしていました。次の bash スクリプトを使用します。
$ cat read.sh
#!/bin/bash
read -s foo
echo $foo
実行strace ./read.sh
してすぐに Ctrl-C を押すと、次のようになります。
...
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon -echo ...}) = 0
brk(0x1a93000) = 0x1a93000
read(0, Process 25487 detached
<detached ...>
PID 25487 があった場所read.sh
。これにより、端末は同じ壊れた状態のままになります。ただし、strace -I1 ./read.sh
単に./read.sh
プロセスを中断し、通常の壊れていない端末に戻ります。