Bash 后台执行未返回

Bash 后台执行未返回

我正在尝试编写一个脚本,其目的是并行化在后台运行进程的执行(创建一些文件的程序),并且当 for 循环中的所有命令完成时,将执行一个额外的命令(即移动所有生成的命令)另一个文件夹中的文件)。这就是我目前得出的结论:

#!/bin/bash

for f in ./lqns/*.lqn
do
    java -jar DiffLQN.jar $f &
done
mv ./lqns/*.csv csvs

并行性有效,但它们永远不会到达线路mv,终端会等待并且不会返回。为什么它不回来?我该如何解决?

也许问题出&在决赛上?因为它等待另一个命令但没有更多?即使添加mv我认为可以解决问题的行......

答案1

如果 csv 文件是由 java 命令生成的,则这将失败,因为它将mv在生成任何文件之前运行。由于所有 java 进程都发送到后台,因此循环几乎会立即完成,因此脚本继续执行,mv找不到要移动的文件,因此不执行任何操作。

一个简单的解决方案是使用wait.来自help wait(在 bash shell 中):

$ help wait 
wait: wait [-fn] [-p var] [id ...]
    Wait for job completion and return exit status.
    
    Waits for each process identified by an ID, which may be a process ID or a
    job specification, and reports its termination status.  If ID is not
    given, waits for all currently active child processes, and the return
    status is zero.  If ID is a job specification, waits for all processes
    in that job's pipeline.

这里的相关位是“如果未给出 ID,则等待所有当前活动的子进程”。这意味着您可以wait在循环之后添加,这将使脚本等到所有子进程完成后再继续:

#!/bin/bash

for f in ./lqns/*.lqn
do
    java -jar DiffLQN.jar "$f" &
done

wait

mv ./lqns/*.csv csvs

或者,您可以组合javamv命令:

#!/bin/bash

for f in ./lqns/*.lqn
do
    java -jar DiffLQN.jar "$f" && mv /lqns/*.csv csvs &
done

另一个可能更好的选择是使用 GNU parallel(它应该位于您正在运行的任何操作系统的存储库中),这是一个专门为此类事情而设计的工具。有了它,你可以做到:

parallel java -jar DiffLQN.jar ::: ./lqns/*.lqn
mv ./lqns/*.csv csvs

相关内容