无法使用GNU Parallel启动作业

时间:2015-07-13 10:49:59

标签: gnu-parallel

我正在运行32核机器,我希望并行化一个非常简单的操作。 给定ip_addresses.txt文件,例如:

1.2.3.4
8.8.8.8
120.120.120.120

我想使用名为script.sh的脚本来解析这些IPS,该脚本将IP解析为各自的ISP。给出一个IP,并输出以下内容,例如给定1.2.3.4,这很好:

echo 1.2.3.4 | ./script.sh
1.2.3.4|Google

ip_addresses.txt包含数百万个唯一的IP,我正在考虑并行调用脚本。 所以我尝试了这个:

cat ip_addresses.txt | parallel ./script.sh

但没有输出。我希望有:

1.2.3.4|Google
120.120.120.120|Taiwan Academic Network

这样我就可以将它们重定向到一个文件。

我的脚本如下:

#!/bin/bash
while read ip
do
  ret=$(/home/sco/twdir/product/trunk/ext/libmaxminddb-1.0.3/bin/mmdblookup --file /home/sco/twdir/product/trunk/ext/libmaxminddb-1.0.3/GeoIP2-ISP.mmdb --ip $ip isp 2>/dev/null |  grep -v '^$' | grep -v '^  Could not find' | cut -d "\"" -f 2)
  [[ $ret != "" ]] &&  echo -n "$ip|" && echo $ret;
done

我错过了什么?虽然我查了教程,但我无法解决这个问题。

2 个答案:

答案 0 :(得分:1)

您的脚本从标准输入(STDIN)读取多行。 GNU Parallel默认将参数放在命令行上。要制作GNU Parallel,请在STDIN上输入--pipe。

cat ip_addresses.txt | parallel --pipe ./script.sh

这将为每个核心运行一个作业,并为每个作业传递1 MB的数据。但查找地址实际上不是CPU难,所以你可以为每个CPU运行10个作业(1000%):

cat ip_addresses.txt | parallel -j 1000% --pipe ./script.sh

这可能会达到您的文件句柄限制,因此:

cat ip_addresses.txt |\
  parallel --pipe --block 50m --round-robin -j100 parallel --pipe -j50 ./script.sh

这将并行运行100 * 50 = 5000个作业。

如果您不希望在获得任何输出之前等待处理完整的1 MB,则可以将其降低到1k:

cat ip_addresses.txt | parallel -j 1000% --pipe --block-size 1k ./script.sh

cat ip_addresses.txt |\
  parallel --pipe --block 50k --round-robin -j100 parallel --pipe --block 1k -j50 ./script.sh

答案 1 :(得分:0)

引用并行手册页。

  

对于每行输入,GNU parallel将以行作为参数执行命令。

输入中的每一行都是脚本的命令行参数,而不是标准输入。像这样:

./script.sh 1.2.3.4

你应该重写你的脚本,以便从变量$1读取参数。

#!/bin/bash
ip=$1
ret=$(/home/sco/twdir/product/trunk/ext/libmaxminddb-1.0.3/bin/mmdblookup --file /home/sco/twdir/product/trunk/ext/libmaxminddb-1.0.3/GeoIP2-ISP.mmdb --ip $ip isp 2>/dev/null |  grep -v '^$' | grep -v '^  Could not find' | cut -d "\"" -f 2)
[[ $ret != "" ]] &&  echo -n "$ip|" && echo $ret;

或者您可以使用并行的--pipe选项。

$ cat ip_addresses.txt | parallel --pipe --block-size 10 ./script.sh