我有一个循环文件的 shell 脚本。处理每个文件可能需要几个小时(受 CPU/GPU 限制)。有时我想在循环结束时暂停执行,当文件处理完成时,然后能够稍后恢复,类似于使用 ctrl-z 和 then 暂停的方式,但我希望它fg
完成在实际暂停/进入后台之前当前循环。
基本上,我希望脚本在收到 ctrl-z (或类似的)时,等到它到达某一行后再停止。你如何实现这一目标?
我有一个循环文件的 shell 脚本。处理每个文件可能需要几个小时(受 CPU/GPU 限制)。有时我想在循环结束时暂停执行,当文件处理完成时,然后能够稍后恢复,类似于使用 ctrl-z 和 then 暂停的方式,但我希望它fg
完成在实际暂停/进入后台之前当前循环。
基本上,我希望脚本在收到 ctrl-z (或类似的)时,等到它到达某一行后再停止。你如何实现这一目标?
我会用类似的东西:
然后,在另一个终端中执行它
kill -s SIGUSR1
告诉你的 PID。请阅读
man stty
以查看是否有您想要使用的信号。阅读man signal kill pkill bash
。解决方案
如果我是你,我会让特定行检查特定文件是否存在。如果文件存在,则脚本应向自身发送 SIGSTOP。
我使用文件而不是信号的原因是你不能(或者至少不能轻易)撤销信号。对于文件来说,这很简单;如果您改变主意,只需删除该文件,脚本就不会自行停止。
脚本自行停止后,向其发送 SIGCONT,它将继续。在实践中,您很可能会从启用作业控制的交互式 shell 运行脚本;在这种情况下,shell 将检测脚本何时停止,您将能够随意运行
fg
脚本bg
。脚本是否尝试自动删除文件或允许保留文件并在下一次迭代中导致 SIGSTOP 直到您删除文件,这取决于您。
Note
kill -s STOP "$$"
不等于Ctrl+ z。击键会导致终端(除非配置不同)将 SIGTSTP(而不是 SIGSTOP)发送到整个前台进程组。如果您确定解释脚本的 shell 是其进程组的领导者,那么您可能需要kill -s TSTP -- "-$$"
. 如果您的脚本启动也在进程组中的异步进程并且您也想停止它们,则向该组发送信号将会产生影响。当进程收到 SIGSTOP(不能被捕获、阻止或忽略)或 SIGTSTP(可以)时,它们的行为可能会有所不同。kill …
根据您的需要调整命令。概念证明
以下脚本是否会自行停止,具体取决于 是否存在
/tmp/blocker
,但它只会在循环迭代结束时执行此操作for
,而不是在中间执行。