使用xargs调用shell函数

时间:2012-06-12 19:23:12

标签: bash sh xargs

我正在尝试使用xargs并行调用更复杂的函数。

#!/bin/bash
echo_var(){
    echo $1
    return 0
}
seq -f "n%04g" 1 100 |xargs -n 1 -P 10 -i echo_var {} 
exit 0

这会返回错误

xargs: echo_var: No such file or directory

关于如何使用xargs来完成此任务或任何其他解决方案的任何想法都将受到欢迎。

5 个答案:

答案 0 :(得分:140)

导出函数应该这样做(未经测试):

export -f echo_var
seq -f "n%04g" 1 100 | xargs -n 1 -P 10 -I {} bash -c 'echo_var "$@"' _ {}

您可以使用内置printf代替外部seq

printf "n%04g\n" {1..100} | xargs -n 1 -P 10 -I {} bash -c 'echo_var "$@"' _ {}

此外,使用return 0exit 0会掩盖其前面的命令可能产生的任何错误值。此外,如果没有错误,这是默认值,因此有点多余。

正如@phobic的评论所指出的,Bash命令可以简化为

bash -c 'echo_var "{}"'

直接在其中移动{}。但是,我更喜欢其他格式,因为它将Bash语法和xargs语法分开。

答案 1 :(得分:16)

使用GNU Parallel看起来像这样:

#!/bin/bash
echo_var(){
    echo $1
    return 0
}
export -f echo_var
seq -f "n%04g" 1 100 | parallel -P 10 echo_var {} 
exit 0

如果您使用的是版本20170822,只要您运行此版本,就不需要export -f

. `which env_parallel.bash`
seq -f "n%04g" 1 100 | env_parallel -P 10 echo_var {} 

答案 2 :(得分:7)

这样的事情也应该起作用:

function testing() { sleep $1 ; }
echo {1..10} | xargs -n 1 | xargs -I@ -P4 bash -c "$(declare -f testing) ; testing @ ; echo @ "

答案 3 :(得分:0)

也许这是不好的做法,但如果您在.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

答案 4 :(得分:0)

似乎我无法发表评论:-(

我想知道关注的重点

bash -c 'echo_var "$@"' _ {}
vs
bash -c 'echo_var "{}"'

第一个将{}替换为bash的arg,而第二个替换为函数的arg。示例1不会扩展$(date)的事实只是一个副作用。

如果您不希望函数args扩展,请使用单引号而不是双引号。为了避免混乱的嵌套,请使用双引号(在另一个引号上扩展args)

$ echo '$(date)' | xargs -0 -L1 -I {} bash -c 'printit "{}"'
Fri 11 Sep 17:02:24 BST 2020

$ echo '$(date)' | xargs -0 -L1 -I {} bash -c "printit '{}'"
$(date)