并行执行命令并等待

时间:2016-12-14 08:28:37

标签: bash

我有一组脚本,例如

01_some_stuff1
02_some_stuff2
03_some_stuff3a
03_some_stuff3b
04_some_stuff4a
04_some_stuff4b

这些脚本应按其编号排序,并且具有相同编号的脚本应并行运行。

我的第一个想法是迭代可能的数字

for n in $(seq -f %02.0f 0 99); do
    for s in "${n}_*"; do
        export CURRENT_JOB="${s}"
        "${s}" &
    done
    wait
done

这是一种安全的方法吗?是否有更优雅的解决方案,也允许为内循环元素设置不同的环境?

2 个答案:

答案 0 :(得分:3)

你可以像这样使用 GNU Parallel

#!/bin/bash

# Don't barf if no matching files when globbing
shopt -s nullglob

for n in $(printf "%02d " {1..4}); do
   # Get list (array) of matching scripts
   scripts=( ${n}_* )
   if [ ${#scripts[@]} -gt 0 ]; then
      parallel --dry-run -k 'CURRENT_JOB={} ./{}' ::: ${scripts[@]}
   fi
   echo barrier
done

示例输出

CURRENT_JOB=01_some_stuff1 ./01_some_stuff1
barrier
CURRENT_JOB=02_some_stuff2 ./02_some_stuff2
barrier
CURRENT_JOB=03_some_stuff3a ./03_some_stuff3a
CURRENT_JOB=03_some_stuff3b ./03_some_stuff3b
CURRENT_JOB=03_some_stuff3c ./03_some_stuff3c
barrier
CURRENT_JOB=04_some_stuff4a ./04_some_stuff4a
CURRENT_JOB=04_some_stuff4b ./04_some_stuff4b
barrier

删除echo barrier--dry-run以便正确运行它。

答案 1 :(得分:2)

您需要的唯一真正的改变是避免引用模式中的*。如果您使用bash 4.0或更高版本,则可以使用大括号扩展来消除对seq的依赖。

# for n in $(seq -f %02.0f 0 99); do
for n in {00..99}; do
    for s in "${n}"_*; do
        export CURRENT_JOB="${s}"
        "${s}" &
    done
    wait
done