如何在for循环中循环浏览一小部分选项?

时间:2019-05-02 21:15:12

标签: 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

如果我不在乎将作业发送到哪台计算机,则删除@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
...

2 个答案:

答案 0 :(得分:1)

这样的事情应该为您完成大部分工作:

#!/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,然后在执行命令时检查它是否为空。

希望这可以帮助您实现大部分目标。如果您对我在这里所做的任何事情有任何疑问,请告诉我。

答案 1 :(得分:1)

遍历机器阵列

#!/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
相关问题