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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:14:10  来源:igfitidea点击:

Calling shell functions with xargs

bashshxargs

提问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 printfinstead 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 0and exit 0like 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 0exit 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.

这类似于使用参数化SQL查询来避免注入

I'm using datein a command substitution or in escaped quotes here instead of the rmcommand used in Sasha's comment since it's non-destructive.

我在这里使用date命令替换或转义引号而不是rmSasha 评论中使用的命令,因为它是非破坏性的。

回答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 -fas 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 .bashrcor 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