
O Virtualbox tem a capacidade de emitir um comando para uma VM em execução:
vboxmanage controlvm NameOfRunningVM acpipowerbutton
No entanto, este comando retorna imediatamente, o que resulta em um desligamento não normal para minha situação.
A situação: pretendo usar isso em um script /etc/init.d. Isso permitiria o desligamento normal de todas as VMs em execução. Atualmente, quando emito o vboxmanage controlvm NameOfRunningVM acpipowerbutton
comando, o desligamento é interrompido porque o comando não espera o desligamento da VM.
Preciso de um script Bash que receba como entrada o nome da máquina Virtualbox e um tempo limite em segundos e aguarde a VM retornar ao estado "desligado" ou o tempo limite ocorre?
Não tenho certeza de qual é a melhor maneira de fazer isso.
Estava pensando em verificar o estado da VM com o seguinte comando:
[user@machine ~]$ vboxmanage list runningvms
"VirtualMachineName" {65c93f1f-4508-4119-b07d-ce9e89b23b8e}
O script bash talvez estivesse pesquisando uma lista de VMs em execução. Assim que o nome da máquina parar de ser listado, a VM será considerada concluída.
Responder1
Usando polling, isso poderia ser feito assim:
#!/bin/bash
MACHINE=$1
echo "Waiting for machine $MACHINE to poweroff..."
until $(VBoxManage showvminfo --machinereadable $MACHINE | grep -q ^VMState=.poweroff.)
do
sleep 1
done
Responder2
a mesma ideia de @larstobi, mas com menos barulho transferindo o comando poll para watch:
$ vboxmanage list vms
"guest" {fubar-rabuf-bufu}
$ vboxmanage showvminfo guest | grep -i state
State: running (since 2020-08-05T02:37:13.784000000)
$ printf '( watch -te -- "! vboxmanage showvminfo guest | grep -i poweroff" >&- & wait )' | time -p bash
Command terminated by signal 2
real 5.05
user 0.00
sys 0.00
O -e
sinalizador causa saída com resultado diferente de zero do comando, enquanto -t
desativa cabeçalhos irritantes; fechamos o stdout para watch, pois o objetivo é bloquear e rodamos em fork, enquanto tecnicamente o bloqueio wait
é interrompível.
Estou passando a string de comando para time -p bash
, para que possa anexá-la facilmente time
para fins desta demonstração, mas na prática, você poderia simplesmente fazer:
$ ( watch -te -- "! expression" >&- & wait )
Isenção de responsabilidade: nada disso foi realmente testado