¿Secuencia de comandos Bash para esperar a que se apague la VM de Virtualbox?

¿Secuencia de comandos Bash para esperar a que se apague la VM de Virtualbox?

Virtualbox tiene la capacidad de emitir un comando a una máquina virtual en ejecución:

vboxmanage controlvm NameOfRunningVM acpipowerbutton

Sin embargo, este comando regresa inmediatamente, lo que resulta en un cierre no correcto para mi situación.

La situación: planeo usar esto en un script /etc/init.d. Esto permitiría un apagado ordenado de todas las máquinas virtuales en ejecución. Actualmente, cuando emito el vboxmanage controlvm NameOfRunningVM acpipowerbuttoncomando, el apagado se interrumpe porque el comando no espera a que se apague la VM.

Necesito un script Bash que tome como entrada el nombre de la máquina Virtualbox y un tiempo de espera en segundos, luego espere a que la VM vuelva al estado de "apagado" o se agote el tiempo de espera.

No estoy seguro de cuál es la mejor manera de hacer esto.


Estaba pensando en comprobar el estado de la VM con el siguiente comando:

[user@machine ~]$ vboxmanage list runningvms
"VirtualMachineName" {65c93f1f-4508-4119-b07d-ce9e89b23b8e}

El script bash tal vez estaría sondeando una lista de máquinas virtuales en ejecución. Una vez que el nombre de la máquina deje de aparecer en la lista, la VM se considerará terminada.

Respuesta1

Usando encuestas, se podría hacer así:

#!/bin/bash
MACHINE=$1
echo "Waiting for machine $MACHINE to poweroff..."

until $(VBoxManage showvminfo --machinereadable $MACHINE | grep -q ^VMState=.poweroff.)
do
  sleep 1
done

Respuesta2

La misma idea que @larstobi, pero menos complicaciones al descargar el comando encuesta para ver:

$ 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

La -ebandera provoca la salida con un resultado del comando distinto de cero, mientras que -tdesactiva los molestos encabezados; Cerramos stdout para watch, ya que el propósito es bloquear y ejecutamos en fork, aunque técnicamente el bloqueo waites interrumpible.

Estoy pasando la cadena de comando a time -p bash, para poder adjuntarla fácilmente timepara los propósitos de esta demostración, pero en la práctica, podrías simplemente hacer:

$ ( watch -te  -- "! expression" >&- & wait )

Descargo de responsabilidad: nada de esto está realmente probado

información relacionada