bash 使用 xargs 调用 shell 函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11003418/
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
Calling shell functions with xargs
提问by fac3
I am trying to use xargs to call a more complex function in parallel.
我正在尝试使用 xargs 并行调用更复杂的函数。
#!/bin/bash
echo_var(){
echo
return 0
}
seq -f "n%04g" 1 100 |xargs -n 1 -P 10 -i echo_var {}
exit 0
This returns the error
这将返回错误
xargs: echo_var: No such file or directory
Any ideas on how I can use xargs to accomplish this, or any other solution(s) would be welcome.
欢迎任何有关如何使用 xargs 来完成此操作的想法,或任何其他解决方案。
回答by Paused until further notice.
Exporting the function should do it (untested):
导出函数应该这样做(未经测试):
export -f echo_var
seq -f "n%04g" 1 100 | xargs -n 1 -P 10 -I {} bash -c 'echo_var "$@"' _ {}
You can use the builtin printf
instead of the external seq
:
您可以使用内置printf
而不是外部seq
:
printf "n%04g\n" {1..100} | xargs -n 1 -P 10 -I {} bash -c 'echo_var "$@"' _ {}
Also, using return 0
and exit 0
like that masks any error value that might be produced by the command preceding it. Also, if there's no error, it's the default and thus somewhat redundant.
此外,使用return 0
和exit 0
类似的方法会掩盖其前面的命令可能产生的任何错误值。此外,如果没有错误,它是默认值,因此有些多余。
@phobic mentions that the Bash command couldbe simplified to
@phobic 提到 Bash 命令可以简化为
bash -c 'echo_var "{}"'
moving the {}
directly inside it. Butit's vulnerable to command injectionas pointed out by @Sasha.
{}
直接在里面移动。但正如@Sasha 所指出的那样,它很容易受到命令注入的影响。
Here is an example why you should not usethe embedded format:
下面是一个为什么不应该使用嵌入格式的例子:
$ echo '$(date)' | xargs -I {} bash -c 'echo_var "{}"'
Sun Aug 18 11:56:45 CDT 2019
Another example of why not:
为什么不的另一个例子:
echo '\"; date\"' | xargs -I {} bash -c 'echo_var "{}"'
This is what is output using the safe format:
这是使用安全格式输出的内容:
$ echo '$(date)' | xargs -I {} bash -c 'echo_var "$@"' _ {}
$(date)
This is comparable to using parameterizedSQL queriesto avoid injection.
I'm using date
in a command substitution or in escaped quotes here instead of the rm
command used in Sasha's comment since it's non-destructive.
我在这里使用date
命令替换或转义引号而不是rm
Sasha 评论中使用的命令,因为它是非破坏性的。
回答by Ole Tange
Using GNU Parallel is looks like this:
使用 GNU Parallel 是这样的:
#!/bin/bash
echo_var(){
echo
return 0
}
export -f echo_var
seq -f "n%04g" 1 100 | parallel -P 10 echo_var {}
exit 0
If you use version 20170822 you do not even have to export -f
as long as you have run this:
如果你使用 20170822 版本,你甚至export -f
不必运行这个:
. `which env_parallel.bash`
seq -f "n%04g" 1 100 | env_parallel -P 10 echo_var {}
回答by Eremite
Something like this should work also:
像这样的事情也应该有效:
function testing() { sleep ; }
echo {1..10} | xargs -n 1 | xargs -I@ -P4 bash -c "$(declare -f testing) ; testing @ ; echo @ "
回答by xdhmoore
Maybe this is bad practice, but you if you are defining functions in a .bashrc
or other script, you can wrap the file or at least the function definitions with a setting of allexport
:
也许这是不好的做法,但是如果您在.bashrc
脚本或其他脚本中定义函数,则可以使用以下设置包装文件或至少包装函数定义allexport
:
set -o allexport
function funcy_town {
echo 'this is a function'
}
function func_rock {
echo 'this is a function, but different'
}
function cyber_func {
echo 'this function does important things'
}
function the_man_from_funcle {
echo 'not gonna lie'
}
function funcle_wiggly {
echo 'at this point I\'m doing it for the funny names'
}
function extreme_function {
echo 'goodbye'
}
set +o allexport