Search code examples
awkgrepvirsh

Checking if a vm status is running using virsh and grep - not working when vm name has a space


Hi I am using this script to check if a vm is running or not before doing an action

#!/bin/bash
vm="PopOS VNC"
vmstate=$(virsh list --all | grep " $vm " | awk '{ print $3}')

if [ "$vmstate" == "x" ] || [ "$vmstate" != "running" ]
then
    echo "VM is shut down" 
else
    echo "VM is running!"
fi

When the vm is running but vm variable has a space the script doesnt work as expected

vm="PopOS VNC"

With the VM running the value of vmstate is "VNC" not "running" as expected

With the vm stopped value is still "VNC"

However it works as expected for a vm name without a space (as below)

vm="CentOS10"

With the VM running the value of vmstate is "running" as expected.

With the VM shutdown the value is "shut" as expected

Please can someone tell me how to get this to work with a vm that has a space in its name.

many thanks :)

edit output of virsh list --all

 Id   Name                  State
--------------------------------------
 -    Big Sur               shut off
 -    True NAS              shut off
 -    CentOS10              shut off
 -    Debian-10             shut off
 -    dos_6.22              shut off
 -    Windows 95            shut off
 -    Gparted Live          shut off
 -    Popos AMD gpu         shut off
 -    PopOS VNC             shut off
 -    OpenSUSE              shut off
 -    Windows 98 VNC        shut off
 -    OpenSUSE2             shut off
 -    pfSense               shut off

output of script using set x

+ vm='PopOS VNC'
++ virsh list --all
++ awk '{ print $3}'
++ grep ' PopOS VNC '
+ vmstate=VNC
+ '[' VNC == x ']'
+ '[' VNC '!=' running ']'
+ echo 'VM is shut down'
VM is shut down
+ set +x

Solution

  • I assume there is a problem with quotes " or ' or both.

    In order to debug your script and see the actual commands expansion by the shell I use set -x to start commands echo and set +x to stop command echo.

    Suggest to run the following script:

    #!/bin/bash
    set -x
    vm="PopOS VNC"
    vmstate=$(virsh list --all | grep " $vm " | awk '{ print $3}')
    
    if [ "$vmstate" == "x" ] || [ "$vmstate" != "running" ]
    then
        echo "VM is shut down" 
    else
        echo "VM is running!"
    fi
    set +x
    

    I assume there is problem with variable expansion in grep " $vm "

    Please post your results in the post.

    In addition remember that awk default field separator is . When your $vm is 2 worded the required awk field is shifted right to: awk '{ print $4}', and if the $vm is 3 worded the required awk field is awk '{ print $5}'.

    Maybe it is better to take the last word awk '{ print $NF}'

    Or to take one word before the last word awk '{ print $(NF - 1)}'