我有一个四行文本文件,每行有 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
/ -0
still 会阻塞引号和反斜杠,并删除前导空格。对于 GNU xargs
(您必须使用它,因为您已经在使用-P
GNU 扩展),最好是将-d '\n'
每一行输入作为单独的参数传递
xargs -a txt -rd'\n' -P2 -n1 bash -c 'foo "$2" "$1"' bash "$a"
(bash
对1
输入的每一行调用一次调用,其中 和 当前行的内容作为单独的参数,在内联 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