多个shell脚本工作者

时间:2017-06-24 19:22:47

标签: bash shell

我们想解释大量的坐标,并使用多个工作人员对它们做些什么。 我们得到了什么:

coords.txt

100, 100, 100
244, 433, 233
553, 212, 432
776, 332, 223
...
8887887, 5545554, 2243234

worker.sh

coord_reader='^([0-9]+), ([0-9]+), ([0-9]+)$'
while IFS='' read -r line || [[ -n "$line" ]]; do
    if [[ $line =~ $coord_reader ]]; then

        x=${BASH_REMATCH[1]}
        y=${BASH_REMATCH[2]}
        z=${BASH_REMATCH[3]}
        echo "x is $x, y is $y, z is $z"
fi

done < "$1"

要执行 worker.sh ,请致电bash worker.sh coords.txt

Bc我们需要分配 coords.txt 所需的数百万个坐标,并创建多个执行相同任务的工作人员,例如每个工作人员coordsaa, coordsab, coordsac

因此,我们使用coords.txt分割split

split -l 1000 coords.txt coords

但是,如何为每个工人分配一个文件?

我是stackoverflow的新手,随时发表评论,以便提高我的提问技巧。

2 个答案:

答案 0 :(得分:4)

从bash运行worker以处理大量文件:

文件架构:

files/ runner.sh worker.sh 

files/:它是一个包含大量文件的文件夹(例如1000)
runner.sh:发动很多工人 worker.sh file:处理文件的任务

例如:

<强> worker.sh

#!/usr/bin/env bash

sleep 5
echo $1

要在每个工作人员files/中运行所有文件,请执行以下操作:

<强> runner.sh:

#!/usr/bin/env bash

n_processes=$(find files/ -type f | wc -l)
echo "spawning  ${n_processes}"

for file in $(find . -type f); then
    bash worker.sh "${file}" &
done

wait
  

/!\ 1000流程很多!!

最好创建一个&#34;流程池&#34; (这里它只保证同时运行最多一个进程,旧的子进程不会被重用于新任务,但在任务完成或失败时就会死掉):

#!/usr/bin/env bash

n_processes=8
echo "max of processes:  ${n_processes}"

for file in $(find files/ -type f); do
    while [[ $(jobs -r | wc -l) -gt ${n_processes} ]]; do
       :
    done
    bash worker.sh "${file}" &
    echo "process pid: $! finished"
done

wait

它实际上不是一个流程池,但它避免了同时存在大量进程,同时存活的进程数最多由n_processes给出。

执行bash runner.sh

答案 1 :(得分:1)

我会用 GNU Parallel 来做这件事。假设您希望一次运行8名工作人员,直到完成所有处理:

parallel -j 8 --pipepart -a coords.txt --fifo bash worker.sh {}

其中:

  • -j8表示“一次保留8个作业”
  • - pipepart表示“将输入文件拆分为部分”
  • -a coords.txt表示“这是输入文件”
  • - fifo表示“创建临时fifo以发送数据,并将其名称保存在{}中以传递给您的工作人员脚本”