在for循环中使用bash等待

时间:2018-04-13 18:23:01

标签: bash shell

(我已经搜索并预计此问题之前已经被问过,但是虽然有很多类似的问题但是找不到这样的问题)

我希望这个for循环在3个不同的线程/进程中运行,wait似乎是正确的命令

for file in 1.txt 2.txt 3.text 4.txt 5.txt
        do something lengthy &
        i=$((i + 1))
        wait $!
done

但是这个构造,我想,只是启动一个线程然后等到它完成它才启动下一个线程。我可以将wait置于循环之外,但我如何

  1. 访问pids?
  2. 将其限制为3个帖子?

4 个答案:

答案 0 :(得分:3)

jobs内置可以列出当前正在运行的后台作业,因此您可以使用它来限制您创建的数量。要将工作限制为三个,请尝试以下方法:

for file in 1.txt 2.txt 3.txt 4.txt 5.txt; do
  if [ $(jobs -r | wc -l) -ge 3 ]; then
    wait $(jobs -r -p | head -1)
  fi

  # Start a slow background job here:
  (echo Begin processing $file; sleep 10; echo Done with $file)&
done
wait # wait for the last jobs to finish

答案 1 :(得分:2)

GNU Parallel可能值得一看。

我的第一次尝试,

parallel -j 3 'bash -c "sleep {};   echo {};"' ::: 4 1 2 5 3
根据并行的发明人,

可以缩短为

parallel -j3 sleep {}\; echo {} ::: 4 1 2 5 3
1
2
4
3
5

并屏蔽分号,更友好的类型,如下:

parallel -j3 sleep {}";" echo {} ::: 4 1 2 5 3

也有效。

它看起来并不简单,到目前为止我只测试了2次,一次回答这个问题。 parallel --help显示了一个源,其中有更多信息,手册页有点令人震惊。 :)

parallel -j 3 "something lengthy {}" ::: {1..5}.txt

可能有效,取决于something lengthy是一个程序(精细)还是只是bashcode(afaik,你不能只是并行调用一个bash函数)。

在xUbuntu-Linux 16.04上,没有安装parallel而是在repo中。

答案 2 :(得分:1)

以Rob Davis为基础'回答:

#!/bin/bash
qty=3

for file in 1.txt 2.txt 3.txt 4.txt 5.txt; do
    while [ `jobs -r | wc -l` -ge $qty ]; do
        sleep 1
        # jobs #(if you want an update every second on what is running)
    done
    echo -n "Begin processing $file"
    something_lengthy  $file &
    echo $!
done
wait

答案 3 :(得分:0)

您可以使用子shell方法示例

 ( (sleep 10) &
    p1=$!
    (sleep 20) &
    p2=$!
    (sleep 15) &
    p3=$!
    wait
    echo "all finished ..." )

注意等待调用等待子shell内的所有子进程,你可以使用模数运算符(%)和3并使用提醒来检查第一个第二和第三个进程id(如果需要)或者可以用它来运行3个并行线程。 希望这会有所帮助。