Bash-Skript zum Warten auf das Herunterfahren der Virtualbox-VM?

Bash-Skript zum Warten auf das Herunterfahren der Virtualbox-VM?

Virtualbox kann einer laufenden VM einen Befehl erteilen:

vboxmanage controlvm NameOfRunningVM acpipowerbutton

Dieser Befehl wird jedoch sofort zurückgegeben, was in meiner Situation zu einem nicht ordnungsgemäßen Herunterfahren führt.

Die Situation: Ich plane, dies in einem /etc/init.d-Skript zu verwenden. Dies würde ein ordnungsgemäßes Herunterfahren aller laufenden VMs ermöglichen. Derzeit vboxmanage controlvm NameOfRunningVM acpipowerbuttonwird das Herunterfahren abgebrochen, wenn ich den Befehl ausgebe, da der Befehl nicht wartet, bis die VM heruntergefahren ist.

Ich brauche ein Bash-Skript, das als Eingabe den Namen der Virtualbox-Maschine und ein Timeout in Sekunden verwendet und dann wartet, bis die VM in den Zustand „Ausgeschaltet“ zurückkehrt oder das Timeout auftritt?

Ich bin nicht sicher, was der beste Weg ist, dies zu tun.


Ich dachte daran, den Status der VM mit dem folgenden Befehl zu überprüfen:

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

Das Bash-Skript würde möglicherweise eine Liste laufender VMs abfragen. Sobald der Maschinenname nicht mehr aufgeführt wird, gilt die VM als beendet.

Antwort1

Mithilfe von Polling könnte dies folgendermaßen erfolgen:

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

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

Antwort2

gleiche Idee wie @larstobi, aber weniger Aufwand durch Auslagerung der Umfrage auf den Überwachungsbefehl:

$ 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

Das -eFlag bewirkt das Beenden bei einem Befehlsergebnis ungleich Null und -tschaltet störende Header aus. Wir schließen stdout für die Überwachung, da der Zweck das Blockieren ist, und führen es im Fork aus, wobei das Blockieren technisch gesehen waitunterbrechbar ist.

Ich übergebe die Befehlszeichenfolge an time -p bash, damit ich sie timefür diese Demonstration problemlos anhängen kann. In der Praxis könnten Sie jedoch auch einfach Folgendes tun:

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

Haftungsausschluss: nichts davon wurde wirklich getestet

verwandte Informationen