在 bash 中中断 for 循环,但仅在迭代完成后才中断?

在 bash 中中断 for 循环,但仅在迭代完成后才中断?

有没有办法中断/停止为了-循环bash,但仅当前迭代已完成 - 即。 “之间”完毕

我正在运行一个为了- 在多个目录上循环,使用一个命令,除非允许完成,否则可能具有破坏性 - 所以我想在命令完成一个目录时但在下一个目录开始之前停止它。

(是的,我知道我可以在之前添加一个sleep或一个read命令完毕- 但是我没有,并且循环已经在运行...)

答案1

为了已经运行:假设命令是程序因此小时候就跑步过程在运行脚本(或其一部分)的 shell 下,该脚本没有给它一个用于输入的heredoc或herestring或者它已读取或至少缓冲了该输入,您可以停止之后过程完成经过:

  • kill -STOPshell(所以它不会做任何事情当前命令)
  • 等待子进程完成并进入僵尸状态
  • kill -KILL贝壳

(当然,都是同一个用户或root来自另一个 shell 的。)如果 的主体do ... done在每次迭代中执行两个或更多操作,则只会在之后捕获它A需要足够长的实时时间的程序,您可以获取该-STOP程序,这可能是也可能不是迭代中的最后一个程序。

在某些(很多?)情况下,它会在kill -KILL前面简单地处理 shell,这会阻止 shell 像平常一样清理其子级,并让子级运行并最终被init(或系统上的等效项)收获。然而,这可能导致子级看到一些 I/O 错误或环境差异或与它的任何孙级的错误或变化,这可能仍然会触发您试图避免的“破坏性”结果。

答案2

根据迭代包含的内容及其构建方式,您也许能够取消可执行文件的链接,然后中断脚本。例如,脚本如下所示:

do_first_thing && \
do_second_thing && \
do_third_thing

假设您可以do_first_thing全局取消链接/移动,也就是说,当目前没有其他脚本需要它时,您:

  • 取消链接或重命名它,以便脚本不会启动它
  • 观察ps迭代的进度
  • 当循环开始空闲重复时,您可以杀死它。

您还可以将脚本中的第一个命令链接到另一个包含sleep或的脚本,read这将为您提供时间和机会来无害地打破循环。

相关内容