Virtualbox VM のシャットダウンを待機する Bash スクリプト?

Virtualbox VM のシャットダウンを待機する Bash スクリプト?

Virtualbox には、実行中の VM にコマンドを発行する機能があります。

vboxmanage controlvm NameOfRunningVM acpipowerbutton

ただし、このコマンドはすぐに返されるため、私の状況では正常なシャットダウンが行われません。

状況: これを /etc/init.d スクリプトで使用する予定です。これにより、実行中のすべての VM を正常にシャットダウンできるようになります。現在、コマンドを発行すると、vboxmanage controlvm NameOfRunningVM acpipowerbuttonコマンドが VM のシャットダウンを待たないため、シャットダウンが中断されます。

Virtualbox マシンの名前と秒単位のタイムアウトを入力として受け取り、VM が「電源オフ」状態に戻るかタイムアウトが発生するまで待機する Bash スクリプトが必要ですか?

これを実行する最善の方法が何であるかはわかりません。


次のコマンドで VM の状態を確認しようと考えていました:

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

bash スクリプトは、実行中の VM のリストをポーリングしている可能性があります。マシン名がリストに表示されなくなると、VM は終了したと見なされます。

答え1

ポーリングを使用すると、次のように実行できます。

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

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

答え2

@larstobi と同じアイデアですが、poll を 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

この-eフラグは、コマンドの非ゼロ結果で終了を引き起こし、-t煩わしいヘッダーをオフにします。目的はブロックすることであり、fork で実行するため、watch の stdout を閉じますが、技術的にはブロックするとwait割り込み可能になります。

time -p bashこのデモでは簡単にアタッチできるようにコマンド文字列を に渡していますtimeが、実際には次のようにするだけで済みます。

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

免責事項:これらは実際にテストされたものではありません

関連情報