我想在使用替换字符串(例如:{%}
)时将包含命令列表的文件传递给gnu-parallel。
不幸的是,如果使用替换字符串,gnu-parallel会将文件中的命令解释为/bin/bash
的参数。
这就是我想要做的:
parallel -j 8 'CUDA_VISIBLE_DEVICES=$(({%} - 1)) {}' < commands.txt
commands.txt
的内容为:
/path/to/binary -arg1 a -arg2 1.0
/path/to/binary -arg1 a -arg2 1.1
...
/path/to/binary -arg1 z -arg2 9.9
但是,这会引发以下错误:
/bin/bash: /path/to/binary -arg1 a -arg2 1.0: command not found
我希望运行GNU Parallel:
CUDA_VISIBLE_DEVICES=0 /path/to/binary -arg1 a -arg2 1.0
环境变量CUDA_VISIBLE_DEVICES
的目的是使每个进程在不同的GPU上运行(默认情况下,所有进程在同一GPU上运行)。如果我不需要CUDA_VISIBLE_DEVICES
,则以下代码将完美运行:
parallel -j 8 < commands.txt
我该如何解决?
答案 0 :(得分:1)
尽管--colsep
有时可以工作,但这并不总是正确的选择。这将创建文件abc
和def
:
echo 'touch abc\ def' | parallel -v --colsep ' ' A=B {}
通常最好使用eval
取消对表达式的引用:
echo 'touch abc\ def' | parallel -v eval A=B {}
所以:
parallel -j 8 'eval CUDA_VISIBLE_DEVICES=$(({%} - 1)) {}' < commands.txt
如果您经常使用$(({%} - 1))
,请考虑制作自己的替换字符串:
echo '--rpl {%-1}\ $_=slot()-1' >> ~/.parallel/config
parallel -j 8 'eval CUDA_VISIBLE_DEVICES={%-1} {}' < commands.txt
甚至:
echo '--rpl '"'"'{CUDA} $_="CUDA_VISIBLE_DEVICES=".(slot()-1)'"'" >> .parallel/config
parallel -j 8 'eval {CUDA} {}' < commands.txt
答案 1 :(得分:0)
使用$line
可以达到目的:
--colsep ' '