我想在使用替换字符串时将包含命令列表的文件传递给 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
我该如何解决这个问题?
最佳答案
虽然--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
关于gpu - 强制 gnu-parallel 将替换字符串视为命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54243732/