问题 Shell Scripting:使用xargs执行shell函数的并行实例


我正在尝试在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并行,我只是没有权限在我写这篇文章的地方安装软件。


11924
2017-07-23 19:33


起源



答案:


这是一个如何使您的功能工作的演示:

$ 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 功能所以 bash 那 xargs spawns将看到它并逃脱函数名称和转义大括号之间的空间。你应该能够适应这种情况在你的情况下工作。你需要调整参数 -P 和 -n (或删除它们)以满足您的需求。

你可以摆脱它 grep 和 cut。如果你正在使用Bash内置 time,您可以使用指定输出格式 TIMEFORMAT 变量。如果你正在使用GNU /usr/bin/time,你可以使用 --format 论据。这些中的任何一个都可以让你放弃 -p 也。

你可以替换你的这一部分 wget 命令: 2>&1 1>/dev/null 同 -q。在任何情况下,你都有逆转。正确的顺序是 >/dev/null 2>&1


11
2017-07-23 23:03



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


答案:


这是一个如何使您的功能工作的演示:

$ 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 功能所以 bash 那 xargs spawns将看到它并逃脱函数名称和转义大括号之间的空间。你应该能够适应这种情况在你的情况下工作。你需要调整参数 -P 和 -n (或删除它们)以满足您的需求。

你可以摆脱它 grep 和 cut。如果你正在使用Bash内置 time,您可以使用指定输出格式 TIMEFORMAT 变量。如果你正在使用GNU /usr/bin/time,你可以使用 --format 论据。这些中的任何一个都可以让你放弃 -p 也。

你可以替换你的这一部分 wget 命令: 2>&1 1>/dev/null 同 -q。在任何情况下,你都有逆转。正确的顺序是 >/dev/null 2>&1


11
2017-07-23 23:03



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


在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 '{}'

1
2017-07-24 15:21





如果在另一个系统上安装GNU Parallel,您将看到该功能位于单个文件中(称为并行)。

您应该能够将该文件简单地复制到您自己的〜/ bin中。


0
2017-07-23 21:43