强制 gnu-parallel 将替换字符串视为命令
Force gnu-parallel to treat replacement string as command
我想在使用替换字符串时将包含命令列表的文件传递给 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 与 运行 并行:
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 ' '
就可以了:
parallel -j 8 --colsep ' ' 'CUDA_VISIBLE_DEVICES=$(({%} - 1)) {}' < 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
我想在使用替换字符串时将包含命令列表的文件传递给 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 与 运行 并行:
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 ' '
就可以了:
parallel -j 8 --colsep ' ' 'CUDA_VISIBLE_DEVICES=$(({%} - 1)) {}' < 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