2017-10-06 85 views
3

我有以下while循环并行运行。 (该logProcess就是我前面在我的脚本中定义的功能。)如何在bash中并行循环?

while read LINE; do 
    logProcess $LINE & 
done <<< "$ELS_LOGS" 
wait 

我需要找到一种方法来限制运行的进程数。我知道有并行进程正在运行。如何转换循环以使用该命令?

+0

也许在循环内部,您可以检查ps -ef和grep * log *过程并检查行数[wc -l]。如果这超过了要运行的进程数,则可以休眠一段时间,直到其中一个进程已完成,然后再次启动新的logProcess。 那是什么要求? –

+0

'logProcess $ LINE',而不是'logProcess“$ LINE”'?请记住,如果你有一行包含'*'的行,你会得到放在命令行上的文件名列表。 –

回答

2

我可以向你推荐GNU并行。你的整个脚本将变成:

parallel -a "$ELS_LOGS" logProcess 

如果logProcess是你的脚本中定义的函数,则需要先运行之前将其导出GNU并行,像这样:

export -f logProcess 

然后,如果你想要一次运行8个,你只需要:

parallel -j 8 -a "$ELS_LOGS" logProcess 

如果你想看看它会做什么,而不是真的做摹什么:

parallel --dry-run ... 

如果你想有一个进度条,或ETA:

parallel --eta ... 
parallel --bar ... 
+0

该脚本包含更多功能,不能像上面那样运行。理想情况下,我需要平行化循环部分。 –

+0

不知道我明白 - 我的建议与你所要求的相同。你的问题不代表你想要什么? –

+0

@MatthewBullock,如果你的函数调用其他函数,*也导出其他函数*。相反,如果你的函数需要修改全局共享状态,那么你有一个你不能在shell中执行的工作(不使用磁盘或其他外部存储进行协调):Shell不支持线程(如果你有多个线程共享相同变量状态的执行);相反,所有*它的选项都是多处理风格,其中每个子进程都有自己的变量,工作目录等。 –

1

GNU xargs也是这项工作的适当工具:

xargs -P 20 -d $'\n' -n 1 logProcess 

...会运行多达20个并发logProcess实例,将stdin的每一行都传递给xargs传递给另一个此类实例。