GNU Parallel:使用-q选项时如何取消分号引号以执行多命令?
解决GNU Parallel使用--quote/-q时执行多条命令的分号引号问题
当使用GNU Parallel的--quote/-q选项时,命令中的分号会被自动添加引号,导致它无法作为Shell的命令分隔符生效,比如执行以下命令时:
$ parallel --dry-run -q command1 {1} \; command2 ::: "With a space" "Another space" "Yet more spaces" "WithoutASpace" command1 'With a space' ';' command2 command1 'Another space' ';' command2 command1 'Yet more spaces' ';' command2
这里的';'会被当作command1的参数,而不是用来执行后续的command2。要让分号正常作为命令分隔符,可采用以下两种方法:
方法1:用bash -c封装多条命令
将需要执行的多条命令打包成一个Shell命令字符串,通过bash -c来执行,这样分号会被Shell解析为命令分隔符,同时-q选项会正确处理带空格的参数:
$ parallel --dry-run -q bash -c 'command1 "$1"; command2' _ {} ::: "With a space" "Another space" "Yet more spaces" "WithoutASpace" bash -c 'command1 "$1"; command2' _ 'With a space' bash -c 'command1 "$1"; command2' _ 'Another space' bash -c 'command1 "$1"; command2' _ 'Yet more spaces' bash -c 'command1 "$1"; command2' _ 'WithoutASpace'
其中_是bash -c命令的$0参数占位符,{}会被传递为$1,确保带空格的参数能正确传递给command1。
方法2:定义Shell函数并调用
如果命令逻辑更复杂,可先定义一个包含多条命令的Shell函数,导出后用Parallel调用:
# 定义函数 my_task() { command1 "$1" command2 } # 导出函数让Parallel能调用 export -f my_task
然后执行Parallel命令:
$ parallel --dry-run -q my_task {} ::: "With a space" "Another space" "Yet more spaces" "WithoutASpace" my_task 'With a space' my_task 'Another space' my_task 'Yet more spaces' my_task 'WithoutASpace'
函数内部的命令分隔逻辑由Shell处理,Parallel仅负责传递参数,既保留了-q的参数保护能力,又能正确执行多条命令。
原理说明
-q选项的作用是对命令行中的每个元素进行引号转义,避免参数中的特殊字符被Shell解析错误,但这也会把分号这类Shell语法元素转义成普通字符。通过将多条命令交给Shell(bash -c或函数)处理,就能让分号恢复命令分隔符的功能,同时利用-q确保带空格、特殊字符的参数被正确传递。
内容的提问来源于stack exchange,提问作者Geremia
相关产品推荐
相关产品推荐

