我有一个示例脚本,如下所示,我将服务器名称作为逗号分隔的stings传递,并为每个服务器执行函数。现在我需要批量执行此操作,例如在第一批函数中将调用a,b,c,d。一旦完成,他们将接下来4并调用函数,最后他们将调用最后2.我无法更改'servers'变量。任何想法/建议。
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;
请注意,服务器变量长度不是固定的,并且根据环境加载不同的服务器。
答案 0 :(得分:3)
将服务器列表读入数组,然后使用子字符串扩展(又名“切片”)。如果我(现在)了解您对服务器列表大小的关注,您还可以存储要在数组中调用的函数的名称。
IFS=, read -a s <<< "$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
答案 1 :(得分:0)
更新受@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
答案 2 :(得分:0)
对我来说,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