我如何在脚本中运行bash命令,而脚本的其余部分不必等待单个bash命令完成执行

时间:2020-07-04 04:52:58

标签: bash multithreading shell

我正在脚本中运行一个循环,并且该脚本中有一个单独的命令需要花费很长时间才能运行。循环运行时,由于该命令的完成,需要很长时间才能完成。这个长命令要求执行所有其他代码。因此,我希望脚本继续运行,而不是等待该长指令完成执行。

Internet上的所有网站都说在长命令的末尾使用&符号来运行单独的线程。问题是,当我使用此命令时,它会忽略前面的将命令设置为可用的行。脚本的其余部分不需要完成该命令。该链接显示2张图像。第一个显示预期的结果,第二个显示在长命令末尾使用&符号时的较差结果。

First Image is the desired setup and the second is the setup when using the & sign at the end of the long command line

这是我正在使用的类似代码示例:

for ((i = 1 ; i <= $howeverManyUserWants ; i++)); do

rm '/path/to/temporaryFile.js'

sed s/codeToChange/randomNum <path/to/template > path/to/temporaryFile.js

node temporaryFile.js #this takes command takes a long time to run

rm  path/to/temporaryFile.js

done

2 个答案:

答案 0 :(得分:0)

从表面上看,该问题要求并行运行一个长时间运行的作业以节省执行时间。作业本身似乎是一个仿真,每次迭代使用不同的随机数(s ... randomNum)。通过OP,不可能知道该作业需要哪些资源。

当前代码的一个问题是它重复使用相同的临时文件。如果节点引擎在执行rm之前无法读取临时文件,则会造成计时问题。

可能的解决方案:


for ((i = 1 ; i <= $howeverManyUserWants ; i++)); do
{
    sed s/codeToChange/randomNum <path/to/template > path/to/temporaryFile-$i.js
    node temporaryFile$i.js #this takes command takes a long time to run
    rm -f path/to/tempporaryFile$i.js
} &
sleep 1
done

建议进行睡眠以避免“雷声”效应,在该效应中,节点的所有实例将同时启动。上面的代码假定节点脚本可以并行工作,并且不使用会相互覆盖的临时文件,等等。

答案 1 :(得分:-1)

问题是,由于我不明白您想要在程序中的那一点同步线程的确切时间。等待作业完成可以使用 jobs 命令完成。使用 jobs 命令,您还可以让系统一次运行任意数量的作业。

我在这里为您提供完整的解决方案,该解决方案允许您设置计算机上的线程数。这样一来,就不会发生“雷鸣”效应,因为一旦系统中有线程,那么一次运行的作业就会很多:

#! /bin/bash

NUM_THREADS=4

for ((i = 1 ; i <= $howeverManyUserWants ; i++)); do
    while true
    do
        CNT=$(jobs -p | wc -l)
        if [[ $CNT -lt $NUM_THREADS ]]; then

                echo "($i from $howeverManyUserWants)"
                {
                        sed s/codeToChange/randomNum < path/to/template > path/to/temporaryFile$i.js
                        node temporaryFile$i.js
                        rm -f path/to/temporaryFile$i.js
                } &
                break
        fi
    done
done
相关问题