
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 )
免責事項:これらは実際にテストされたものではありません