Bash predicate with several boolean functions

592 views Asked by At

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?

1

There are 1 answers

3
Fred On

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 of return $? is redundant (a function, left to itself, always returns the return code of the last statement executed before exiting the function).