SIGTSTP(Ctrl-Z)は、スクリプトコマンドで開始されたスクリプトでは機能しません。

SIGTSTP(Ctrl-Z)は、スクリプトコマンドで開始されたスクリプトでは機能しません。

注:stdinとstdoutをファイルに書き込むコマンドをscript示します。script

scriptこのユーティリティを使用して、端末のテキストの色を維持しながら後で確認できるように出力を保存するスクリプトを実行しようとしています。

  • CtrlZ+()を使用して現在のスクリプトを一時停止しようとすると、SIGTSTPコンソールが印刷され、^Zスクリプトは停止しません。
  • Ctrlそれから+を試しました。S ( SIGSTOP)。現在実行中のスクリプトは停止しますが(htopすべてのプロセスをZモーダルとして表示)、端末を解放するわけではありません。  Ctrl+Q実際にそれらを回復しなさい。

今はなぜか混乱しています。SIGSTOP Ctrl+Sは有効ですがSIGTSTPCtrl+ Z)は無効です。

詰まる可能性があることを知っていますが、そうする理由はなく、SIGTSTPマニュアルページにもこれについての内容はありません。script私はスクリプトインタプリタをインタラクティブモードに強制的に切り替えようとしましたが、結果は私をさらに混乱させました。Ctrl+ Z()を実行すると、SIGTSTP実行中のスクリプトは停止しますが、scriptスクリプトが完了した後に終了し、停止した子プロセスがすべて終了することを示します。

このような状況で優雅に耐える方法はありますか?また、何が起こっているのかを正確に説明できる人はいますか?

答え1

他のパススルーツール(sshなど)と同様に、Ctrl / Zなどの文字が割り込みをscreen生成しないように、呼び出し端末を生モードに切り替えます。その後、これらの文字を渡し、内部端末装置はそれを「正常に」処理して予想される信号を生成します。すべてのプロセスはキャプチャを選択できますが、キャプチャすることはできません。tmuxscriptSIGTSTPSIGSTOP

$この例では、コマンドラインプロンプトを表示するために使用します。

$ 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.

関連情報