スクリプト コマンドによって開始されたスクリプトでは SIGTSTP(Ctrl-Z) が機能しない

スクリプト コマンドによって開始されたスクリプトでは SIGTSTP(Ctrl-Z) が機能しない

注: stdin と stdout をファイルに記録するコマンドscriptを指します。script

scriptターミナル上のテキストの色を保持しながら、後で検査できるように出力を保存するユーティリティを使用してスクリプトを実行しようとしていました 。

  • Ctrl+ Z( )を使用して現在のスクリプトを一時停止しようとするとSIGTSTP、コンソールに出力され^Z、スクリプトは停止しません。
  • 私はその後、Ctrl+を試しましたS SIGSTOP. 現在実行中のスクリプトはフリーズします(htopすべてのプロセスをZモードとして表示します)が、ターミナルは解放されません。  Ctrl+Qはそれらを再開します。

なぜなのか分からなくなってしまったSIGSTOP Ctrl+Sは機能しますが、SIGTSTP( Ctrl+ Z) は機能しません。

トラップできることは知っていますSIGTSTPが、そうする理由が見当たりませんし、scriptのマニュアル ページにもそれについて何も記載されていません。スクリプト インタープリタを強制的に対話モードにしようとしましたが、その結果は私をさらに混乱させました。Ctrl+ Z( SIGTSTP) を発行すると、実行中のスクリプトは一時停止しますが、scriptスクリプトが終了して終了したと表示され、一時停止中の子プロセスはすべて強制終了します。

このような状況で正常にサスペンドを許可する方法はありますか? また、何が起こったのか正確に説明できる人はいますか?

答え1

他のパススルー ツール ( sshscreentmuxなど) と同様に、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を使用して再開しようとすると、セッションが終了します。scriptfg

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

関連情報