Writing bash script and don't know how to use more that one function in predicate:
#!/bin/bash
set -x
WAITED=0
registered () {
VBoxManage showvminfo --machinereadable "$1" 2>/dev/null | grep UUID=
}
not_running () {
VBoxManage showvminfo --machinereadable "$1" 2>/dev/null | grep 'VMState="poweroff"'
}
while registered "$1" && not_running "$1" && [ $WAITED -lt 60 ]
do
echo "LOOP"
VBoxManage controlvm "$1" acpipowerbutton 2>/dev/null
((WAITED++))
sleep 1
done
if registered "$1" && ! not_running "$1"
then
echo "POWEROFF"
VBoxManage controlvm "$1" poweroff 2>/dev/null
sleep 1
fi
if registered "$1"
then
echo "UNREG"
VBoxManage unregistervm "$1" --delete 2>/dev/null
fi
Output:
./stop_vm 1b76
+ WAITED=0
+ registered 1b76
+ VBoxManage showvminfo --machinereadable 1b76
+ grep UUID=
UUID="cee02a9a-9a9a-4313-b297-479ca0a41e01"
+ not_running 1b76
+ VBoxManage showvminfo --machinereadable 1b76
+ grep 'VMState="poweroff"'
+ registered 1b76
+ grep UUID=
+ VBoxManage showvminfo --machinereadable 1b76
UUID="cee02a9a-9a9a-4313-b297-479ca0a41e01"
+ not_running 1b76
+ VBoxManage showvminfo --machinereadable 1b76
+ grep 'VMState="poweroff"'
+ echo POWEROFF
POWEROFF
+ VBoxManage controlvm 1b76 poweroff
+ sleep 1
+ WAITED=0
+ registered 1b76
+ VBoxManage showvminfo --machinereadable 1b76
+ grep UUID=
UUID="cee02a9a-9a9a-4313-b297-479ca0a41e01"
+ not_running 1b76
+ VBoxManage showvminfo --machinereadable 1b76
+ grep 'VMState="poweroff"'
VMState="poweroff"
+ '[' 0 -lt 60 ']'
+ echo LOOP
LOOP
+ VBoxManage controlvm 1b76 acpipowerbutton
+ (( WAITED++ ))
+ sleep 1
+ registered 1b76
+ VBoxManage showvminfo --machinereadable 1b76
+ grep UUID=
UUID="cee02a9a-9a9a-4313-b297-479ca0a41e01"
+ echo UNREG
UNREG
+ VBoxManage unregistervm 1b76 --delete
cara@bmserver1-sandbox:~/vm$ + registered 1b76
+ VBoxManage showvminfo --machinereadable 1b76
+ grep UUID=
+ registered 1b76
+ VBoxManage showvminfo --machinereadable 1b76
+ grep UUID=
+ registered 1b76
+ VBoxManage showvminfo --machinereadable 1b76
+ grep UUID=
Why POWEROFF comes before LOOP? There are no outer loops. What is the correct way to write predicates with several functions?
The problem may be caused by your script being recursively called by the VBox system when executing the body of the
while
loop in the "LOOP" section of your code. If it is the case, then you would need to rework your script to avoid recursion (with some kind of mutex mechanism), or perform the required actions in another script.You should probably quote your expansion of positional arguments (like
"$1"
), and your use ofreturn $?
is redundant (a function, left to itself, always returns the return code of the last statement executed before exiting the function).