如何在不终止 运行 作业的情况下终止 GNU parallel?

How do I terminate GNU parallel without killing running jobs?

我正在 运行 编写一堆 shell 脚本,例如 parallel -a my_scripts bash 在某个时候,我决定我已经 运行 足够多了,我想停止产生新的工作,让所有现有的工作完成。换句话说,我想在不杀死子进程的情况下杀死父进程。

好像有ways of controlling termination when first launching GNU parallel(比如如果我事先知道我只想运行x个工作,那么我可以用--halt now,success=x参数),但是当它已经 运行ning.

时我找不到如何控制 GNU parallel

当然我可以 CTRL+C 终止并行,然后重新运行 中止的作业,但我认为可能有更聪明的方法。

我明白了。答案是简单地将 SIGTERM 发送到 parent parallel 进程(只需 killing 它的 PID 即可)。 parallel 然后响应如下(在本例中我有 4 个工作 运行):

parallel: SIGTERM received. No new jobs will be started.
parallel: Waiting for these 4 jobs to finish. Send SIGTERM again to stop now.

我从手册页中挖出来的:

COMPLETE RUNNING JOBS BUT DO NOT START NEW JOBS
If you regret starting a lot of jobs you can simply break GNU parallel, but if you want to make sure you do not have half-completed jobs you should send the signal SIGTERM to GNU parallel:

killall -TERM parallel

This will tell GNU parallel to not start any new jobs, but wait until the currently running jobs are finished before exiting.

UPDATE(如果你有新版本的 parallel >= 20190322):根据@Bowi 的评论,“自 2019 年以来,它不再是 SIGTERM,而是 SIGHUP(例如,使用 kill -HUP $PARALLEL_PID)。 SIGTERM 现在终止 children 而不让它们完成。”参见 https://superuser.com/questions/1660301/gnu-parallel-is-behaving-differently-on-sigterm-in-two-cygwin-installation and http://git.savannah.gnu.org/cgit/parallel.git/tree/NEWS#n687

如果您在简单脚本中使用并行,则需要添加少量内容:
如果您在看起来像这样的简单 script.sh 中使用并行 (<= 20190322):

#!/bin/bash
cd $(dirname [=10=])

seq -w 0 $((-1)) | parallel -j+0 --progress ./something.exe {}

可以查script.sh的子进程的PID(使用pgrep -P $scriptsh_pid),然后使用

kill -TERM $child_process_pid

如果我的 shell 中只有 运行 script.sh,killall -TERM perl 也可以。