如何在bash中并行循环?
我有以下while
循环并行运行。 (该logProcess
就是我前面在我的脚本中定义的功能。)如何在bash中并行循环?
while read LINE; do
logProcess $LINE &
done <<< "$ELS_LOGS"
wait
我需要找到一种方法来限制运行的进程数。我知道有并行进程正在运行。如何转换循环以使用该命令?
我可以向你推荐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 ...
该脚本包含更多功能,不能像上面那样运行。理想情况下,我需要平行化循环部分。 –
不知道我明白 - 我的建议与你所要求的相同。你的问题不代表你想要什么? –
@MatthewBullock,如果你的函数调用其他函数,*也导出其他函数*。相反,如果你的函数需要修改全局共享状态,那么你有一个你不能在shell中执行的工作(不使用磁盘或其他外部存储进行协调):Shell不支持线程(如果你有多个线程共享相同变量状态的执行);相反,所有*它的选项都是多处理风格,其中每个子进程都有自己的变量,工作目录等。 –
GNU xargs
也是这项工作的适当工具:
xargs -P 20 -d $'\n' -n 1 logProcess
...会运行多达20个并发logProcess
实例,将stdin的每一行都传递给xargs
传递给另一个此类实例。
也许在循环内部,您可以检查ps -ef和grep * log *过程并检查行数[wc -l]。如果这超过了要运行的进程数,则可以休眠一段时间,直到其中一个进程已完成,然后再次启动新的logProcess。 那是什么要求? –
'logProcess $ LINE',而不是'logProcess“$ LINE”'?请记住,如果你有一行包含'*'的行,你会得到放在命令行上的文件名列表。 –