%20%E3%81%8C%E6%A9%9F%E8%83%BD%E3%81%97%E3%81%AA%E3%81%84.png)
注: stdin と stdout をファイルに記録するコマンドscript
を指します。script
script
ターミナル上のテキストの色を保持しながら、後で検査できるように出力を保存するユーティリティを使用してスクリプトを実行しようとしていました 。
- Ctrl+ Z( )を使用して現在のスクリプトを一時停止しようとすると
SIGTSTP
、コンソールに出力され^Z
、スクリプトは停止しません。 - 私はその後、Ctrl+を試しましたS
(. 現在実行中のスクリプトはフリーズします(SIGSTOP
)htop
すべてのプロセスをZ
モードとして表示します)が、ターミナルは解放されません。 Ctrl+Qはそれらを再開します。
なぜなのか分からなくなってしまった
Ctrl+Sは機能しますが、SIGSTOP
SIGTSTP
( Ctrl+ Z) は機能しません。
トラップできることは知っていますSIGTSTP
が、そうする理由が見当たりませんし、script
のマニュアル ページにもそれについて何も記載されていません。スクリプト インタープリタを強制的に対話モードにしようとしましたが、その結果は私をさらに混乱させました。Ctrl+ Z( SIGTSTP
) を発行すると、実行中のスクリプトは一時停止しますが、script
スクリプトが終了して終了したと表示され、一時停止中の子プロセスはすべて強制終了します。
このような状況で正常にサスペンドを許可する方法はありますか? また、何が起こったのか正確に説明できる人はいますか?
答え1
他のパススルー ツール ( ssh
、screen
、tmux
など) と同様に、script
は呼び出し端末を raw モードに設定し、Ctrl/Z などの文字によって割り込みが生成されないようにします。 次に、これらの文字を渡し、内部の端末デバイスがそれらを「通常どおり」処理して、期待される信号を生成します。 どのプロセスでも をトラップすることはできますSIGTSTP
が、 をキャッチすることはできませんSIGSTOP
。
$
これらの例では、コマンド ライン プロンプトを示すために次のものを使用しました。
$ script
Script started, output log file is 'typescript'.
$ sleep 5 # After starting this I hit Ctrl/Z
[1]+ Stopped sleep 5
$
script
自分自身にシグナルを送信するとSIGTSTP
、混乱しているようで (プログラミングの障害でしょうか?)、SIGCONT
再開しません。ただし、送信SIGINT
またはその他の終了シグナルは、script
元のアクションを実行して一時停止するのに十分な時間再開します。その後、次のコマンドSIGTSTP
を使用して再開しようとすると、セッションが終了します。script
fg
$ script
Script started, output log file is 'typescript'.
$ while date; do sleep 5; done
Mon, 15 Apr 2024 14:44:42
Mon, 15 Apr 2024 14:44:47
この時点でscript
受信されSIGTSTP
、内部プロセスの実行が停止しました。その後の送信ではSIGCONT
目に見える変化はありませんでした。
送信するSIGINT
と次のようになります:
Mon, 15 Apr 2
[1]+ Stopped script
そしてコマンドを再開します:
$ fg
script
Session terminated, killing shell... ...killed.
Script done.
SIGSTOP
内部のプロセスに送信する方がよいと思われますscript
。別の例を次に示します。
$ script
Script started, output log file is 'typescript'.
$ while date; do sleep 5; done
Mon, 15 Apr 2024 14:48:31
Mon, 15 Apr 2024 14:48:36
Mon, 15 Apr 2024 14:48:41
Mon, 15 Apr 2024 14:48:46 # Here I sent SIGSTOP to the shell running the "while" loop
Mon, 15 Apr 2024 14:49:07
Mon, 15 Apr 2024 14:49:12 # Here I hit Ctrl/C to break the loop
$ exit
Script done.