【问题标题】:How to feed a large array of commands to GNU Parallel?如何向 GNU Parallel 提供大量命令?
【发布时间】:2013-05-07 19:18:33
【问题描述】:

我正在评估GNU Parallel 是否可用于搜索并行存储在系统上的文件。系统上一年中的每一天 (doy) 只能有一个文件(因此每年最多有 366 个文件)。假设系统上有 3660 个文件(大约 10 年的数据)。系统可以是多CPU多核Linux或多CPU Solaris。

我正在存储要在数组中的文件上运行的搜索命令(每个文件一个命令)。这就是我现在正在做的事情(使用 bash),但是我无法控制并行启动多少搜索(绝对不想一次启动所有 3660 搜索):

#!/usr/bin/env bash
declare -a cmds
declare -i cmd_ctr=0

while [[ <condition> ]]; do
    if [[ -s $cur_archive_path/log.${doy_ctr} ]]; then
      cmds[$cmd_ctr]="<cmd_to_run>"
      let cmd_ctr++
    fi
done

declare -i arr_len=${#cmds[@]}
for (( i=0; i<${arr_len}; i++ ));
do
  # Get the command and run it in background
  eval ${cmds[$i]} &
done
wait

如果我要使用parallel(它会自动计算出最大CPUs/cores 并且只开始并行搜索这么多),我如何才能并行重用数组cmds 并重写上面的代码?另一种选择是将所有命令写入文件,然后执行cat cmd_file | parallel

【问题讨论】:

  • 学究起来,在我的宇宙中,10 年不能产生 3660 个文件,因为不可能有 10 个连续的闰年。但既然你写了“关于”,我假设你知道这一点,并且不要从平行宇宙中瞥见我的(这让我有点难过);-)
  • @Adrian 你是对的;我添加了“关于”来说明闰年:)

标签: bash parallel-processing gnu-parallel


【解决方案1】:

https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Using-shell-variables 说:

parallel echo ::: "${V[@]}"

你不想要回声,所以:

parallel ::: "${cmds[@]}"

如果您不需要 $cmds 做其他任何事情,请使用 'sem'(它是并行 --semaphore 的别名)https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Working-as-mutex-and-counting-semaphore

while [[ <condition> ]]; do
  if [[ -s $cur_archive_path/log.${doy_ctr} ]]; then
    sem -j+0 <cmd_to_run>
  fi
done
sem --wait

您还没有描述 可能是什么。如果您只是在执行类似 for 循环的操作,则可以将整个脚本替换为:

parallel 'if [ -s {} ] ; then cmd_to_run {}; fi' ::: $cur_archive_path/log.{1..3660}

(基于https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Composed-commands)。

【讨论】:

  • 感谢所有提示。但我有一种感觉,如果 "${cmds[@]}" 被内联扩展,特别是如果 cmds 数组中有 1000 个元素/命令,shell 会爆炸?认为从文件中输入命令更安全?
  • 另外,当${cmds[@]} 展开时,多个命令之间的分隔符是什么(我是否需要在每个命令的末尾使用;)?这与cat cmd_file | parallel 我认为换行符被视为命令分隔符有什么不同?
  • 我可以运行 130KB 的命令行,所以如果你的命令
  • 分隔符是数组元素。因此,您可以在每个元素中添加任何内容 - 无需以 ; 结尾。主要区别在于命令行长度(您清楚地知道)。但是为什么不直接尝试一下:运行一些长度和内容与实际命令相似的“echo”命令。这应该会让你更有信心相信它会奏效。
  • 还有一个问题,有没有办法可以限制使用并行时输出的总行数?例如,每个数据文件包含 30,000 条记录,但随后有 10 个这些文件。我想并行搜索所有 10 个文件,但不希望搜索返回 100,000 条记录(假设每次搜索有 10,000 条记录),客户端无法处理。我可以将所有结果发送到一个文件,然后执行head -n 30000 并告诉文件的位置/使其可供下载。或者我可以简单地做:cat cmd_file | parallel -j30% | head -n 30000
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-07
  • 1970-01-01
  • 2019-04-12
  • 2020-12-07
  • 1970-01-01
  • 2017-09-09
  • 1970-01-01
相关资源
最近更新 更多