我正在尝试使用GNU Parallel来运行具有多个二进制标志的脚本。我想启用/禁用这些,如下所示:
给定一个名为"sample.py
",有两个选项,"--seed
";它接受一个整数和"--something
";这是一个二进制标志,不接受输入,我想构造一个并行调用,产生以下调用:
python sample.py --seed 1111
python sample.py --seed 1111 --something
python sample.py --seed 2222
python sample.py --seed 2222 --something
python sample.py --seed 3333
python sample.py --seed 3333 --something
我试过
parallel python sample.py --seed {1} {2} ::: 1111 2222 3333 ::: "" --something
parallel python sample.py --seed {1} {2} ::: 1111 2222 3333 ::: '' --something
parallel python sample.py --seed {1} {2} ::: 1111 2222 3333 ::: --something
但没有任何运气。我试图用GNU并行实现的目标是可能的吗?我可以修改我的脚本以显式地为标志取TRUE/FALSE值,但如果可能的话,我宁愿避免这样做。
你是。
GNU平行引号替换字符串。这通常是有意义的,因为给它文件名是安全的,如:
My brother's 12" records, all with ***.csv
否则会给你带来无尽的麻烦。
然而,为了保持一致,GNU Parallel也引用空字符串。这就是你现在的感受
--dry-run
显示发生了什么:
$ parallel --dry-run python sample.py --seed {1} {2} ::: 1111 2222 3333 ::: '' --something
python sample.py --seed 1111 ''
python sample.py --seed 1111 --something
python sample.py --seed 2222 ''
python sample.py --seed 2222 --something
python sample.py --seed 3333 ''
python sample.py --seed 3333 --something
那你怎么才能避免呢?
你可以告诉shell计算所有的字符串:
parallel eval python sample.py --seed {1} {2} ::: 1111 2222 3333 ::: '' --something
但是当你需要手术刀的时候,这可能有点钝。从版本20190722开始,您还可以使用{=uq=}
。uq()
是一个perl函数,它告诉GNU Parallel这个替换字符串不应该被引用:
$ parallel-20190722 --dry-run python sample.py --seed {1} {=2 uq=} ::: 1111 2222 3333 ::: '' --something
python sample.py --seed 1111
python sample.py --seed 1111 --something
python sample.py --seed 2222
python sample.py --seed 2222 --something
python sample.py --seed 3333
python sample.py --seed 3333 --something
> bash$ cat sample.py
#!/usr/bin/python3
import sys
import time
time.sleep(0.2)
print(sys.argv)
> bash$ cat split.sh
#!/bin/sh
exec $*
> bash$ for seed in 1111 2222 3333; do
printf "%s " "$seed" "$seed --something";
done
| xargs -0 parallel
sh split.sh python3 sample.py --
['sample.py', '1111', '--something']
['sample.py', '1111']
['sample.py', '2222']
['sample.py', '2222', '--something']
['sample.py', '3333', '--something']
['sample.py', '3333']
解释:
第一部分,循环,只是创建参数列表:
1111
1111 --something
2222
2222 --something
3333
3333 --something
xargs
将把这个列表从stdin发送到parallel
的参数。
split.sh
通过空格分隔其参数—这里我们假设脚本的参数中没有空格。
我们调用sh split.sh
,它将通过拆分参数(如2222 --something
)到2222
和--something
来执行命令。
这些参数将传递给python3 sample.py
,因此您将得到一个由parallel
运行的类似python3 sample.py 2222 --something
的shell命令。
如果我们不使用split.sh
直接调用python (xargs -0 parallel python3 sample.py --
),那么当xargs
将2222 --something
作为单个参数传递时,parallel
将运行类似于python3 sample.py '2222 --something'
的内容。