Bash-скрипт для ожидания выключения виртуальной машины Virtualbox?

Bash-скрипт для ожидания выключения виртуальной машины Virtualbox?

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 )

Отказ от ответственности: ничего из этого на самом деле не проверено

Связанный контент