Visão geral:
Salvei minha variável em um arquivo de configuração e liguei mais tarde.
Cada entrada com o nome FailOverVM tem um número ao lado dele como FailOverVM1 e eu quero verificar se ele tem dados e gerar uma função chamada FailOverVM1 () que mais tarde no script inicia $ FailOverVM1Name, que por acaso é 'Plex Servidor '
Eu posso fazer manualmente como StartVM1 () e eu trabalho, mas eu posso expandir para 15 depois e querer que ele seja ajustado de acordo.
Para esclarecer, posso iniciar a VM com uma declaração de caso mais tarde e ter, mas não consigo enrolar minha cabeça em torno da variável que em si é uma variável. Espero não ter confundido ninguém. Talvez eu esteja fazendo este caminho mais complicado do que é ou precisa ser.
#!/bin/bash
. "${BASH_SOURCE%/*}/configlocation.conf"
. $Configuration
checkVM1=$(nc -vvz $FailOverVM1IP $FailOverVM1Port 2>&1)
VMCount=$(grep "FailOverVM.Name" /media/VirtualMachines/Current/Configuration.conf | wc -l)
pinggateway=$(ping -q -w 1 -c 1 'ip r | grep default | cut -d ' ' -f 3' > /dev/null && echo ok || echo error = error)
STATE="error";
while [ $STATE == "error" ]; do
#do a ping and check that its not a default message or change to grep for something else
STATE=$(ping -q -w 1 -c 1 'ip r | grep default | cut -d ' ' -f 3' > /dev/null && echo ok || echo error)
#sleep for 2 seconds and try again
sleep 2
done
for i $VMCount; do
if [ -z "$FailOverVM$VMCountName" ];
echo "$FailOverVM$VMCountName"
fi
done
StartVM1(){
if [[ $checkVM1 = "Connection to $FailOverVM1IP $FailOverVM1Port port [tcp/*] succeeded!" ]]; then
echo '$FailOverVM1Name is up'
else
echo "$FailOverVM1Name down"
su -c 'VBoxManage startvm $FailOverVM1Name -type headless' vbox
fi
}
Onde eu cheguei até agora em um script de teste
#!/bin/bash
. "${BASH_SOURCE%/*}/configlocation.conf"
. $Configuration
Pre='$FailOverVM'
post="FailOverVM"
name="Name"
VMCount=$(grep "FailOverVM.Name" $Configuration | wc -l) #Count entires in config file wirn FailOverVM*Name
while [[ $i -le $VMCount ]]
do
#if [ -z $Pre$i"Name" ];then #If the variable $FailOverVM*Name is not blank
$post$i=$Pre$i$Name
echo "$post$i" #print it
#else
# echo $Pre$i"Name" "was empty"
#fi
((i = i + 1))
done
Saída:
./net2.sh: line 11: FailOverVM=$FailOverVM: command not found
FailOverVM
./net2.sh: line 11: FailOverVM1=$FailOverVM1: command not found
FailOverVM1
./net2.sh: line 11: FailOverVM2=$FailOverVM2: command not found
FailOverVM2
./net2.sh: line 11: FailOverVM3=$FailOverVM3: command not found
FailOverVM3
./net2.sh: line 11: FailOverVM4=$FailOverVM4: command not found
FailOverVM4
./net2.sh: line 11: FailOverVM5=$FailOverVM5: command not found
FailOverVM5
./net2.sh: line 11: FailOverVM6=$FailOverVM6: command not found
FailOverVM6
O problema aqui é que não há $ FailOverVM sem um número ao lado dele, e o que há com o "comando não encontrado FailOverVM5" (ou qualquer outro número) que eu não sabia que emiti um. Mas o maior problema é não pegar a variável $ FailOVerVM * do arquivo de configuração. Eu preciso disso para o loop func.
Novo script modificado com a ajuda @ dave_thompson_085
#!/bin/bash
. "${BASH_SOURCE%/*}/configlocation.conf"
. $Configuration
for i in ${!FailOverName[@]}; do
selip=FailOverIP[${i}]
selport=FailOverPort[${i}]
checkVM[$i]=$(nc -vvz ${!selip} ${!selport} 2>/devnull)
echo ${!selip}
echo ${!selport}
echo FailOverName[${i}]
done
StartVM() { # first argument to a function is accessed as $1 or ${1}
selname=FailOverName[${i}]
if [[ checkVM[$i] =~ 'succeeded' ]]; then # only need to check the part that matters
echo number $i name ${!selname} already up
else
echo starting number $i name ${!selname}
echo su -c "VboxManager startvm '${!selname}' -headless" vbox # note " because ' $
fi
}
#done
StartVM 1 # and
StartVM 2 # etc
Saída
root@6120:~/.scripts# ./net2.sh -v
192.168.1.6
32400
FailOverName[1]
192.168.1.5
80
FailOverName[2]
192.168.1.7
80
FailOverName[3]
192.168.1.1
1030
FailOverName[4]
starting number 4 name finch
su -c VboxManager startvm 'finch' -headless vbox
starting number 4 name finch
su -c VboxManager startvm 'finch' -headless vbox
root@6120:~/.scripts#
Arquivo de configuração
#
FailOverVM1IP='192.168.1.6'
FailOverVM1Port='32400'
FailOverVM1Name='Plex Server'
FailOverVM1NASHDD='/media/VirtualMachines/Current/Plex\ Server/Plex\ Server.vmdk'
FailOverVM1LocalHDD='/home/vbox/VirtualBox\ VMs/Plex\ Server/Plex\ Server.vmdk'
FailOverVM2IP='192.168.1.7'
FailOverVM2Port='32402'
FailOverVM1Name='Plex Server2'
FailOverVM2NASHDD='/media/VirtualMachines/Current/Plex\ Server/Plex\ Server.vmdk'
FailOverVM2LocalHDD='/home/vbox/VirtualBox\ VMs/Plex\ Server/Plex\ Server.vmdk'
FailOverVM3IP='192.168.1.8'
FailOverVM3Port='32403'
FailOverVM3Name='Plex Server3'
FailOverVM3NASHDD='/media/VirtualMachines/Current/Plex\ Server/Plex\ Server.vmdk'
FailOverVM3LocalHDD='/home/vbox/VirtualBox\ VMs/Plex\ Server/Plex\ Server.vmdk'
FailOverVM4IP='192.168.1.9'
FailOverVM4Port='32404'
FailOverVM4Name='Plex Server4'
FailOverVM4NASHDD='/media/VirtualMachines/Current/Plex\ Server/Plex\ Server.vmdk'
FailOverVM4LocalHDD='/home/vbox/VirtualBox\ VMs/Plex\ Server/Plex\ Server.vmdk'
FailOverVM5IP='192.168.1.10'
FailOverVM5Port='32405'
FailOverVM5Name='Plex Server5'
FailOverVM5NASHDD='/media/VirtualMachines/Current/Plex\ Server/Plex\ Server.vmdk'
FailOverVM5LocalHDD='/home/vbox/VirtualBox\ VMs/Plex\ Server/Plex\ Server.vmdk'
FailOverIP[1]=192.168.1.6 FailOverName[1]=robin FailOverPort[1]=32400
FailOverIP[2]=192.168.1.5 FailOverName[2]=bluejay FailOverPort[2]=80
FailOverIP[3]=192.168.1.7 FailOverName[3]=sparrow FailOverPort[3]=80
FailOverIP[4]=192.168.1.1 FailOverName[4]=finch FailOverPort[4]=1030
VM1LogDirLogDir='/media/VirtualMachines/Logs/Plextstart'
PlexServerIP='192.168.1.6'
PlexPort='32400'
mydate='date '+%Y-%m-%d_%H%M''
rsyncfrom=
NASPlexvmHDD='/media/VirtualMachines/Current/Plex\ Server/Plex\ Server.vmdk'
LocalPlexvmDHDD='/home/vbox/VirtualBox\ VMs/Plex\ Server/Plex\ Server.vmdk'
PlexVMname='Plex Server'
PlexStartLogDir='/media/VirtualMachines/Logs/Plextstart'
RouterIp='192.168.1.1'
Então, ele vê todos os vms, mas está executando apenas o último e o dobro disso.
#!/bin/bash
. "${BASH_SOURCE%/*}/configlocation.conf"
. $Configuration
for i in ${!FailOverName[@]}; do
selip=FailOverIP[${i}]
selport=FailOverPort[${i}]
checkVM[$i]=$(nc -vvz ${!selip} ${!selport} 2>&1)
echo ${!selip}
echo ${!selport}
#echo ${i}
#done
StartVM() { # first argument to a function is accessed as $1 or ${1}
selname=FailOverName[${i}]
if [[ $checkVM[$i] =~ 'succeeded' ]]; then # only need to check the part that matters
echo number $i name ${!selname} already up
else
echo starting number $i name ${!selname}
echo su -c "VboxManager startvm '${!selname}' -headless" vbox # note " because ' prevents the variable expansion
fi
}
StartVM
done
Observação: a verificação se a VM já está em execução não funciona ainda, mas essa não foi a pergunta que fiz, portanto, isso atende aos critérios.