Bash 如何在for循环中循环使用一小组选项?
我有一堆作业需要提交到作业队列。队列中有8台不同的机器,我可以从中选择,也可以提交到任何可用的服务器。有时,服务器可能出现故障,因此我希望能够在发送作业的可用服务器之间进行循环。下面是一个赤裸裸的版本Bash 如何在for循环中循环使用一小组选项?,bash,Bash,我有一堆作业需要提交到作业队列。队列中有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 如果我不关
# 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\u job-q server-x python script.py$fn
如果我确实想指定特定的机器,那么我可以通过在machine
asserver@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
,然后在执行命令时检查它是否为空
希望这能让你大部分的时间都在那里。如果您对我在这里所做的任何事情有任何疑问,请告诉我。在机器阵列中循环
#!/bin/bash
rotate() {
if [[ "$1" = "all" ]]; then
machines=(1 2 3 4 5 6 7 8)
else
machines=($*)
fi
idx=0
max=${#machines[@]}
for ((fn=0; fn<20; fn++)); do
if (( $max > 0 )); then
servernr=${machines[idx]}
((idx=(idx+1) % ${max}))
else
servernr=""
fi
echo "submit -q server${servernr} file${fn}"
done
}
# test
echo "Rotate 0 machines"
rotate
echo "Rotate all machines"
rotate all
echo "Rotate some machines"
rotate 2 5 6
#/bin/bash
轮换{
如果[[“$1”=“所有”];则
机器=(12345678)
其他的
机器=($*)
fi
idx=0
max=${机器[@]}
对于((fn=0;fn 0)),则
servernr=${machines[idx]}
((idx=(idx+1)%${max}))
其他的
servernr=“”
fi
echo“submit-q服务器${servernr}文件${fn}”
完成
}
#试验
echo“旋转0台机器”
旋转
echo“旋转所有机器”
全部轮换
echo“旋转一些机器”
轮换2 5 6
难道你不能在for循环中添加一个if语句来检查你是否应该跳过某个变量吗?与问题没有直接关系,但请看一下。@CoffeeTableEspresso我不确定你的意思,for循环会迭代python脚本的参数文件。你能举个例子吗?首先制作一个机器数组并删除那些你想跳过的机器。遍历数组。@WalterA如何遍历它们?我也不想硬编码这个数组