SIGTSTP(Ctrl-Z) 不适用于由脚本命令启动的脚本

SIGTSTP(Ctrl-Z) 不适用于由脚本命令启动的脚本

注意:script指的是script命令,它将 stdin 和 stdout 记录到文件中。

我试图使用该 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将调用终端置于原始模式,以便 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.

相关内容