我有一堆作业需要提交到作业队列。队列有 8 台不同的机器,我可以从中挑选,也可以提交到任何可用的服务器。有时服务器可能出现故障,所以我希望能够循环访问我将作业发送到的可用服务器。下面是准系统版本
# jobscript.sh
dir='some/directory/of/files/to/process'
for fn in $(ls $dir); do
submit_job -q server@machine -x python script.py $fn
done
如果我不关心将作业发送到哪台机器,我会删除 @machine
部分,因此命令只是 submit_job -q server -x python script.py $fn
。
如果我确实想指定特定的机器,那么我通过在 machine
之后附加一个数字来指定哪台机器作为 server@machine1
然后在下一次迭代 server @machine2
然后 server@machine2
等。如果我只使用前 3 个服务器,脚本的输出将如下所示
submit_job -q server@machine1 -x python script.py file1
submit_job -q server@machine2 -x python script.py file2
submit_job -q server@machine3 -x python script.py file3
submit_job -q server@machine1 -x python script.py file4
submit_job -q server@machine2 -x python script.py file5
submit_job -q server@machine3 -x python script.py file6
submit_job -q server@machine1 -x python script.py file7
submit_job -q server@machine2 -x python script.py file8
...
可用服务器列表是 [1, 2, 3, 4, 5, 6, 7, 8]
但我想从命令行另外指定要忽略的服务器列表所以像
$bash jobscript.sh -skip 1,4,8
只会循环 2, 3, 5, 6, 7
并产生输出
submit_job -q server@machine2 -x python script.py file1
submit_job -q server@machine3 -x python script.py file2
submit_job -q server@machine5 -x python script.py file3
submit_job -q server@machine6 -x python script.py file4
submit_job -q server@machine7 -x python script.py file5
submit_job -q server@machine2 -x python script.py file6
submit_job -q server@machine3 -x python script.py file7
submit_job -q server@machine5 -x python script.py file8
submit_job -q server@machine6 -x python script.py file8
...
如果标志 -skip
不存在,只需运行不带 @machine
的命令,这将允许队列决定将作业放置在哪里,命令看起来像
submit_job -q server -x python script.py file1
submit_job -q server -x python script.py file2
submit_job -q server -x python script.py file3
submit_job -q server -x python script.py file4
submit_job -q server -x python script.py file5
submit_job -q server -x python script.py file6
submit_job -q server -x python script.py file7
submit_job -q server -x python script.py file8
submit_job -q server -x python script.py file8
...
最佳答案
这样的事情应该为您完成大部分的工作:
#!/bin/bash
machines=(1 2 3 4 5 6 7 8)
skip_arr=(1 4 8)
declare -a arr
for i in "${machines[@]}"; do
if [[ ! " ${skip_arr[@]} " =~ " $i " ]]; then
arr+=($i)
fi
done
arr_len="${#arr[@]}"
declare -i i=0
for f in $(ls); do
i="i % arr_len"
echo "file is $f, machine is $i"
let i++
done
现在,我已将其设置为遍历当前目录,并只回显机器和文件名的值。显然,您需要将其更改为从正确的目录实际执行命令。
您需要做的最后一件事是从命令行输入构建 skip_arr
,然后在执行命令时检查它是否为空。
希望这能帮助您完成大部分工作。如果您对我在这里所做的任何事情有任何疑问,请告诉我。
关于bash - 如何在 for 循环中循环选择一小组选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55960345/