Bash:后台有多个for循环


8

这是在后台启动多个顺序处理的正确方法吗?

for i in {1..10}; do
    for j in {1..10}; do
        run_command $i $j;
    done &
done;

所有j后应相互给予处理i,但都i应该被同时处理。


您所说的“正确方法”是什么意思?
伊兰·本·纳坦

主要是它起作用。我在stackoverflow上错过了这个。
无线电控制

1
:-)我问是因为您的代码对我来说很好用。如果您以“正确的方式”表示最佳实践,那么我会将内部循环放入函数或什至是其他文件中,以便更加清晰地
看待

Answers:


8

你的外循环基本上是

for i in {1..10}; do
    some_compound_command &
done

这将some_compound_command在后台启动十个并发实例。他们将开始尽可能快地,但不完全“都在同一时间”(即,如果some_compound_command需要短的时间,那么第一个可能是最后一个开始之前完成)。

some_compound_command碰巧是循环的事实并不重要。这意味着您显示的代码是正确的,因为j内部循环的迭代将按顺序运行,但是内部循环的所有实例(外部循环的每个迭代一个i)将同时启动。

唯一要记住的是,每个后台作业都将在子shell中运行。这意味着cd在内部循环的一个实例中,对环境所做的更改(例如,修改shell变量的值,使用更改当前工作目录等)在该特定后台作业之外是不可见的。

您可能想要添加的是wait循环之后的一条语句,至少在脚本终止之前等待所有后台作业实际完成:

for i in {1..10}; do
    for j in {1..10}; do
        run_command "$i" "$j"
    done &
done

wait

3

如果您具有GNU Parallel,则可以执行以下操作:

parallel -j0 'for j in {1..10}; do run_command {} $j; done' ::: {1..10}

好处之一是并行运行的输出run_commands不会混合。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.