Bash script to wait for Virtualbox VM shutdown?

Using polling, it could be done like this:

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

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

same idea as @larstobi, but less fuss by offloading poll to watch command:

$ 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

The -e flag causes exit on non-zero result of command, while -t turns off annoying headers; we close stdout for watch, since the purpose is to block and we run in fork, while technically blocking with wait which is interruptible.

I am passing the command string to time -p bash, so that I can easily attach time for the purposes of this demonstration, but in practice, you could just do:

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

Disclaimer: none of this is really tested