我刚刚了解了大括号扩展,并希望我可以利用它们来启动具有不同命令行参数的相同 C++ 程序。
我的代码从终端运行如下:
mpirun -n 1 main.exe 1 10 0.1 1 5
main.exe 后面的数字是我的程序的输入参数。
我想做这样的事情:
mpirun -n 1 main.exe 1 10 {0.1,0.2} 1 5
我希望代码运行两次,一次使用 0.1,一次使用 0.2 作为第三个参数。
为什么它不起作用以及如何修复它?
最好的
答案1
不,那行不通。当您运行该命令时,大括号扩展将会扩展。只有大括号扩展受到影响,它们不会导致您运行多个命令。在你的情况下,这个:
mpirun -n 1 main.exe 1 10 {0.1,0.2} 1 5
就会简单地变成这样:
mpirun -n 1 main.exe 1 10 0.1 0.2 1 5
如果您想使用不同的值运行两次,您可以这样做:
for i in {0.1,0.2}; do
mpirun -n 1 main.exe 1 10 "$i" 1 5
done
那将会运行
mpirun -n 1 main.exe 1 10 0.1 1 5
其次是
mpirun -n 1 main.exe 1 10 0.2 1 5
当然,在这种特定情况下,大括号扩展不必要地复杂,您应该这样做:
for i in 0.1 0.2; do
mpirun -n 1 main.exe 1 10 "$i" 1 5
done
理解此类事情的一个有用技巧是set -x
(假设您使用的是 bash),它将向您显示实际执行的命令:
$ set -x
$ mpirun -n 1 main.exe 1 10 {0.1,0.2} 1 5
+ mpirun -n 1 main.exe 1 10 0.1 0.2 1 5
[. . .]
您可以使用 再次将其关闭set +x
,但是使用它可以让您准确地看到 shell 如何扩展复杂命令并检查实际执行的内容。
答案2
这个问题确实时不时地出现,普遍的共识是for
循环是实现您想要做的事情的最佳/最安全的方法。
话虽如此,您可以将大括号扩展与这样的构造一起使用(例如四个不同的参数)
printf 'mpirun -n 1 main.exe 1 10 %s 1 5\n' {p1,p2,p3,p4} | sh
即,您通过管道构建多个命令printf
行,并由sh
1执行。
另一种方式:如果你已经gnu parallel
安装了,你可以运行
parallel mpirun -n 1 main.exe 1 10 {} 1 5 ::: {p1,p2,p3,p4}
在这两种情况下,{p1,p2,p3,p4}
都由 shell 扩展,然后使用'和 ' 分别p1 p2 p3 p4
使用(一次一个)(您可以将它们视为占位符...)printf
%s
parallel
{}
如果您尝试在交互模式下保存输入,那么您应该查阅 shell 手册中的历史扩展章节,例如使用zsh
(and setopt histexpand
) 您可以运行命令
mpirun -n 1 main.exe 1 10 0.1 1 5
然后使用历史扩展来运行相同的命令,但使用0.2
第 6 个参数(计数从 0 开始)
!:-5 0.2 !:7*
对于其他值依此类推,例如XYZ
!:-5 XYZ !:7*
1:这假设你知道你在做什么......你不想通过管道传递类似的rm -rf *
东西sh
答案3
mpirun -n 1 main.exe 1 10 {0.1,0.2} 1 5
扩展到
mpirun -n 1 main.exe 1 10 0.1 0.2 1 5
这可能不是你想要的。
请注意,{a,b,c}
扩展到a b c
你可能想跑
for x in 0.1 0.2
do
mpirun -n 1 main.exe 1 10 "$x" 1 5
done
它可以是单行的,但在交互式运行时很难节省击键。