
Virtualbox имеет возможность подать команду работающей виртуальной машине:
vboxmanage controlvm NameOfRunningVM acpipowerbutton
Однако эта команда возвращается немедленно, что приводит к некорректному завершению работы в моей ситуации.
Ситуация: Я планирую использовать это в скрипте /etc/init.d. Это позволит плавно завершить работу всех работающих виртуальных машин. В настоящее время, когда я даю команду, vboxmanage controlvm NameOfRunningVM acpipowerbutton
завершение работы прерывается, поскольку команда не ждет, пока виртуальная машина завершит работу.
Мне нужен скрипт Bash, который принимает в качестве входных данных имя машины Virtualbox и тайм-аут в секундах, а затем ждет, пока виртуальная машина вернется в состояние «poweroff» или истечет тайм-аут?
Я не уверен, как лучше всего это сделать.
Я думал проверить состояние виртуальной машины с помощью следующей команды:
[user@machine ~]$ vboxmanage list runningvms
"VirtualMachineName" {65c93f1f-4508-4119-b07d-ce9e89b23b8e}
Скрипт bash, возможно, будет опрашивать список запущенных виртуальных машин. Как только имя машины перестанет отображаться в списке, виртуальная машина будет считаться завершенной.
решение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, но меньше суеты за счет переноса опроса в команду 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
отключает раздражающие заголовки; мы закрываем stdout для наблюдения, поскольку цель — блокировка, и запускаем fork, хотя технически блокировка с помощью wait
которого прерываема.
Я передаю командную строку в time -p bash
, чтобы ее можно было легко подключить time
для целей этой демонстрации, но на практике вы могли бы просто сделать:
$ ( watch -te -- "! expression" >&- & wait )
Отказ от ответственности: ничего из этого на самом деле не проверено