Shell脚本:使用xargs并行执行shell函数的多个实例

12
我正在尝试在shell脚本中使用xargs来运行我定义的函数的并行实例。该函数计时页面的获取,因此实际上需要以并行进程并发获取页面,而不是在后台进程中获取(如果我的理解有误,并且两者之间几乎没有差异,请告诉我)。这个函数是:
function time_a_url ()
{
     oneurltime=$($time_command -p wget -p $1 -O /dev/null 2>&1 1>/dev/null | grep real | cut -d" " -f2)
     echo "Fetching $1 took $oneurltime seconds."
}

如何使用xargs管道以一种可以接受并行运行time_a_url的次数作为参数的形式来实现此操作?是的,我知道GNU parallel,但我没有在编写代码的地方安装软件的权限。

3个回答

12

以下是一个演示,展示如何使你的函数能够运行:

$ f() { echo "[$@]"; }
$ export -f f
$ echo -e "b 1\nc 2\nd 3 4" | xargs -P 0 -n 1 -I{} bash -c f\ \{\}
[b 1]
[d 3 4]
[c 2]
关键是要使用export导出函数,以便 xargs 生成的 bash 可以看到它,并且要在函数名和转义大括号之间转义空格。您应该能够将其调整为适合您情况的代码。您需要调整 -P-n 的参数(或将其删除)以满足您的需求。

您可以考虑摆脱 grepcut。如果您正在使用 Bash 内置的 time,可以使用 TIMEFORMAT 变量指定输出格式。如果您正在使用 GNU 的 /usr/bin/time,则可以使用 --format 参数。这两种方法都允许您放弃 -p

您可以用 -q 替换您的 wget 命令中的这部分:2>&1 1>/dev/null。不管怎样,您把它们反了过来。正确的顺序应该是 >/dev/null 2>&1


1
我使用了 xargs -P0 -n1 -I{} bash -c "f {}",它仍然有效,并且看起来更加整洁。 - Lee Netherton

1
在Mac OS X上:
xargs:最大进程数必须> 0(对于:xargs -P [> 0])
f() { echo "[$@]"; }
export -f f

echo -e "b 1\nc 2\nd 3 4" | sed 's/ /\\ /g' | xargs -P 10 -n 1 -I{} bash -c f\ \{\}

echo -e "b 1\nc 2\nd 3 4" | xargs -P 10 -I '{}' bash -c 'f "$@"' arg0 '{}'

0
如果您在另一台系统上安装了GNU Parallel,您会发现该功能位于单个文件中(称为parallel)。
您应该能够将该文件简单地复制到自己的~/bin目录下。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接