使用 xargs 和单独的变量并行化函数

使用 xargs 和单独的变量并行化函数

我有一个四行文本文件,每行有 1、2、3 和 4。另外,我有一个想要并行化的函数:foo() { echo "$1 is not $2"; }

我导出函数:export -f foo

现在我想使用文本文件中的参数调用该函数xargs以进行并行化。我还想a=0在函数中使用变量 ( ) 作为参数。所以,我将该函数称为:cat txt | xargs -I "{}" -P 2 bash -c 'foo {} $a'

这会忽略变量 ( a=0)。并输出:

“1 不是”...“4 不是”等等

如果我调用:cat txt | xargs -I "{}" -P 2 bash -c 'foo {} 0'它有效并且我得到正确的输出

“1 不是0“……”4不是0“ ETC

但我需要使用变量 ( a=0) 来调用它,而不是使用零。我该怎么做?

答案1

在 shell 代码中嵌入{}始终是一个坏主意,因为它会引入命令注入漏洞。将数据作为单独的(非代码)参数传递总是更好。

另外-I, without -d/ -0still 会阻塞引号和反斜杠,并删除前导空格。对于 GNU xargs(您必须使用它,因为您已经在使用-PGNU 扩展),最好是将-d '\n'每一行输入作为单独的参数传递

xargs -a txt -rd'\n' -P2 -n1 bash -c 'foo "$2" "$1"' bash "$a"

bash1输入的每一行调用一次调用,其中 和 当前行的内容作为单独的参数,在内联 shell 脚本中$a称为$1和)。$2

或者与-I

xargs -a txt -rd'\n' -P2 -I'{}' bash -c 'foo "$1" "$2"' bash {} "$a"

在这里,您可以切换到zsh具有zargs可自动加载函数的函数,该函数可以像 GNUxargs一样进行并行处理,包括无需运行单独的 shell 调用或导出函数的函数xargs

$ autoload zargs
$ foo() print -r - $1 is not $2
$ zargs -P2 -I {} {1..4} -- foo {} $a
1 is not foo
2 is not foo
3 is not foo
4 is not foo

答案2

使用 GNU Parallel 时,它看起来像这样:

foo() { echo "$1 is not $2"; }
export -f foo
seq 4 > txt
a=0
cat txt | parallel foo {} $a

相关内容