我有一个像下面的示例脚本,我将服务器名称作为逗号分隔的stings传递并执行每个服务器的function。 现在我需要批量执行这个,例如在第一批函数中会调用a,b,c,d。 一旦完成,他们将接下来的4和调用的function,最后他们会打电话给最后2.我不能改变“服务器”variables。 任何ides /build议。
servers = a,b,c,d,e,f,g,h,i,j OIFS=$IFS; IFS=","; for server in ${servers} do function1 server done for server in ${servers} do function2 server done for server in ${servers} do function3 server done IFS=$OIFS;
请注意,服务器可变长度是不固定的,并根据环境加载不同的服务器。
读取服务器列表到一个数组,然后使用子字符串扩展(又名“切片”)。 如果我(现在)了解您对服务器列表大小的关注,也可以存储要在数组中调用的函数的名称。
IFS=, read -as <<< "$servers" bs=4 # batch size for ((i=0; i<=${#s[@]}; i+=bs)); do function1 "${s[@]:i:i+bs}" function2 "${s[@]:i:i+bs}" function3 "${s[@]:i:i+bs}" done
更新灵感来自@chepner的答案,我已经修改了循环,使它也是动态调用的函数。
function1 () { echo "f1: $@"; } function2 () { echo "f2: $@"; } function3 () { echo "f3: $@"; } servers=a,b,c,d,e,f,g,h,i,j slice=4 IFS=, read -r -a array <<< "${servers}" for index in "${!array[@]}" do let "n = (index / slice) + 1" # n = 1 in (0..3), 2 in (4..7), 3 in (8..11), ... function${n} ${array[i]} done
产量
f1:a
f1:b
f1:c
f1:d
f2:e
f2:f
f2:g
f2:h
f3:我
f3:j
显然,这有一个警告:函数必须被称为function1, function2, ...
(实际上函数的名字也可以被重新映射,失去一点活力)。
否则,更经典的静态循环:
for index in "${!array[@]}"; do let "n = (index / slice) + 1" ((n == 1)) && function1 ${array[index]} ((n == 2)) && function2 ${array[index]} ((n == 3)) && function3 ${array[index]} done
看起来像GNU Parallel
的工作对我来说。 像这样的东西:
parallel -d ',' -k -j 4 'func1 {1}; func2 {1}; func3 {1}' <<< $servers
试试看这样:
parallel -d ',' -k -j 4 'echo {1}; sleep 2' <<< $servers a b c d e f g h i j
如果他们真的是函数(而不是shell脚本或可执行文件),请记住像这样导出它们:
func1() { echo Doing it for $1 sleep 2 echo Done with $1 } export -f func1