bash Shell 脚本:使用 xargs 执行 shell 函数的并行实例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3321738/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Shell Scripting: Using xargs to execute parallel instances of a shell function
提问by Gnats
I'm trying to use xargs in a shell script to run parallel instances of a function I've defined in the same script. The function times the fetching of a page, and so it's important that the pages are actually fetched concurrently in parallel processes, and not in background processes (if my understanding of this is wrong and there's negligible difference between the two, just let me know).
我试图在 shell 脚本中使用 xargs 来运行我在同一个脚本中定义的函数的并行实例。该函数对页面的获取进行计时,因此重要的是页面实际上是在并行进程中并发获取的,而不是在后台进程中(如果我对此的理解是错误的并且两者之间的差异可以忽略不计,请告诉我) .
The function is:
功能是:
function time_a_url ()
{
oneurltime=$($time_command -p wget -p -O /dev/null 2>&1 1>/dev/null | grep real | cut -d" " -f2)
echo "Fetching took $oneurltime seconds."
}
How does one do this with an xargs pipe in a form that can take number of times to run time_a_url in parallel as an argument? And yes, I know about GNU parallel, I just don't have the privilege to install software where I'm writing this.
如何使用 xargs 管道以一种可以多次并行运行 time_a_url 作为参数的形式执行此操作?是的,我知道 GNU 并行,我只是没有权限在我写这篇文章的地方安装软件。
采纳答案by Paused until further notice.
Here's a demo of how you might be able to get your function to work:
这是一个演示如何让您的功能正常工作:
$ 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]
The keys to making this work are to exportthe function so the bashthat xargsspawns will see it and to escape the space between the function name and the escaped braces. You should be able to adapt this to work in your situation. You'll need to adjust the arguments for -Pand -n(or remove them) to suit your needs.
以使这项工作的关键在于export功能使bash该xargs产卵会看到它,并逃脱了函数名和逃脱括号之间的空间。您应该能够使其适应您的情况。您需要调整-P和-n(或删除它们)的参数以满足您的需要。
You can probably get rid of the grepand cut. If you're using the Bash builtin time, you can specify an output format using the TIMEFORMATvariable. If you're using GNU /usr/bin/time, you can use the --formatargument. Either of these will allow you to drop the -palso.
您可能可以摆脱grep和cut。如果您使用的是 Bash 内置time,则可以使用该TIMEFORMAT变量指定输出格式。如果您使用的是 GNU /usr/bin/time,则可以使用该--format参数。这些中的任何一个都将允许您删除-p也。
You can replace this part of your wgetcommand: 2>&1 1>/dev/nullwith -q. In any case, you have those reversed. The correct order would be >/dev/null 2>&1.
您可以将wget命令的这一部分替换2>&1 1>/dev/null为-q. 无论如何,你把那些颠倒过来了。正确的顺序是>/dev/null 2>&1。
回答by tmpvar
On Mac OS X:
在 Mac OS X 上:
xargs: max. processes must be >0 (for: xargs -P [>0])
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 '{}'
回答by Ole Tange
If you install GNU Parallel on another system, you will see the functionality is in a single file (called parallel).
如果您在另一个系统上安装 GNU Parallel,您将看到该功能位于单个文件中(称为并行)。
You should be able to simply copy that file to your own ~/bin.
您应该能够简单地将该文件复制到您自己的 ~/bin 中。

