gnu parallel 删除命令中空格字符前的转义符

gnu parallel 删除命令中空格字符前的转义符

我目前正在测试 gnu parallel,以使用 bash 在多个服务器上分发比较命令。在其最基本的功能中,此比较命令需要两个输入进行比较(oracle 数据库访问),并通过 -o 要求输出文件名。程序至少需要执行一个操作加载、保存或直接上传。

compare -o cmp.input1.input2.dat Input1 Input2

我有几千个这样的输入对,并创建一个包含所有组合的文件,以便每行包含输出文件名和程序所需的数据库标识符

#test_parallel
-o cmp.input1.input2.dat Input1 Input2
-o cmp.input1.input3.dat Input1 Input3
-o cmp.input2.input3.dat Input2 Input3
[...]

并使用并行执行命令,但比较命令失败

parallel -a test_parallel "compare {}"
ERROR: No action specified for results (load, save or direct upload)
usage: compare [-u][-o <file>] query target

使用--dryrun模式这是并行执行的:

compare -o\ cmp.input1.input2.dat\ Input1\ Input2

由于某些我无法理解的原因,比较程序无法正确处理转义的空格。在 bash 中执行此命令会导致完全相同的错误消息。删除 -o 标志后的转义(我可以将 -o 移至并行命令)会导致“参数过多”错误。删除所有转义可按预期执行命令。

是否可以告诉 parallel 不要在命令调用上打印转义符?我似乎在文档中找不到任何内容,只是这是预期的默认行为,如parallel --shellquote

答案1

GNU Parallel 将输入视为单个参数并将其括起来,以便您可以安全地使用文件名,例如:

My brother's 12" records costs 30$ each.txt

在您的情况下,您希望 shell 解析该参数,因此空格将不会被引用:

parallel -a test_parallel eval compare {}

或者你也可以按空格分割:

parallel --colsep ' ' -a test_parallel compare {1} {2} {3} {4}

但是,既然您想比较全部与全部,那么您可以做得更优雅:

parallel cmp -o ../out/cmp.{1}.{2} {1} {2} ::: Input* ::: Input*

这会将所有输入*与所有输入*进行比较。--results您可以使用目录结构良好的输出:

parallel --results out/ cmp {1} {2} ::: Input* ::: Input*

但是如果你想cmp InputY InputX在跑完步后跳过跑步cmd InputX InputY,那么你可以这样做:

parallel --results out/ cmp {=1' $arg[1] ge $arg[2] and $job->skip();' =} {2} ::: Input* ::: Input*

编辑:

20190722版本引入了该功能uq

parallel -a test_parallel compare {=uq=}

uq是一个 perl 函数。调用时,GNU Parallel 将避免引用该替换字符串。因此,您可以混合使用带引号和不带引号的替换字符串:

parallel echo {} = {=uq=} ::: \$PWD
# You can change $_ if you want: uq() is a normal perl function
parallel echo {}ME = '{=uq(); $_.="ME"=}' ::: \$HO \$LOGNA

相关内容