Shell awk usage in a simple shell script

I'm trying to modify the start/stop/status script for emulators/virtualbox-ose, because I think there are a few things in it that can be done better. However, it shows how awful I am with scripts. I did find out that awk could be useful to what I am trying to accomplish. Awk can use arrays made from a string with newlines as the separator.

I started with the status script, because that is the simplest. In the current form the script does not look at all registered virtual machines. The bigger problem is that it tries to determine if a machine is powered off or running. A machine can also have the status stopping, or saved. I think it might be better to directly ask VBoxManage.
Also, some of my virtual machines have a whitespace in their name, which does not work with the current script. This is solved in the original script by giving them an alias in /etc/rc.conf.

This is what I have made^H^H^Hstolen:
Code:
#!/bin/sh

. /etc/rc.subr

vboxheadless_users=$(getent group vboxusers | awk -F ':' '/vboxusers/{sub(/,/, " "); print $4}')
for vmuser in ${vboxheadless_users}; do
        vmnames=$(/usr/bin/su ${vmuser} -c "/usr/local/lib/virtualbox/VBoxManage list vms" | awk -F '"' '{print $2}')

        printf '%s\n' "${vmnames}"
done
It first gets the users in the group vboxusers, and for every user VBoxManage is asked for the registered virtual machines. Now I would like to print the state for every registered virtual machine with a for loop.

For instance, this is the information I am after:
Code:
# su vmuser  -c 'VBoxManage showvminfo vmname' | grep State
State:           running (since 2016-09-30T06:25:59.336000000)

My problem is that I can not get the vmnames variable in awk without awk complaining about a newline in the string. There is another way, by executing the VBoxManage command in awk, and splitting that, but I'm already in too deep.

I have tried these (in the for loop):
Code:
awk -v var="${vmnames}" -F "\n" '{split("var", vmarray, "\n"); print var[1]}'

awk -v var="${vmnames}" 'BEGIN { FS = "\n" } ; { split(var, vmarray, "\n") } ; {for (n in vmarray) print n}'

awk -v var="${vmnames}" 'BEGIN { split(var, vmarray, "\n") }'

awk -v var="${vmnames[*]}" 'BEGIN { FS = "\n" } ; { split(var, vmarray, "\n") }'

awk -v var="${vmnames}[*]" 'BEGIN { FS = "\n" } ; { split(var, vmarray, "\n") }'

awk -v var="${vmnames}" 'BEGIN {var=ENVIRON["var"]} ; {split(var, vmarray, "\n")}'

awk  'BEGIN {cmd = "/usr/bin/su ${vmuser} -c \"/usr/local/lib/virtualbox/VBoxManage list vms\"" ; while (cmd | getline result)...

And this is where I gave up. With all these different versions of awk I thought it's best to ask here first. After all, here somebody is not very likely to give a bash-only answer.
And I do not have the idea I'm getting anywhere, so can somebody help me?
I do think the basic concept of using getline to capture the output of a command, split this on every newline , and use a for loop for every element of the array is correct.
 
First question: why awk(1)? Why not one of the scripting languages that are more powerful? Your system almost certainly has Perl installed, and probably Python. Maybe Ruby. All of these can make it much easier to deal with strings.
 
Isn't awk part of the base system? Perl is already a dependency of emulators/virtualbox-ose, so that would be an option. If it would work allright I would ask the port maintainer to maybe switch to this version of the script. Hopefully this will fix PR 212074. Not in the way mentioned above of course, that my status script will magically fix this, but in the end I hope to fix that.
However, the only thing I have done in perl is copy/pasting together a ticketnumber generator for OTRS, so uh, not exactly great. And awk seemed to be somewhat between grep and languages such as perl.
 
use printf instead of print, or change the output record separator

vmnames=$(/usr/bin/su ${vmuser} -c "/usr/local/lib/virtualbox/VBoxManage list vms" | awk -F '"' '{[B]printf[/B] $2}')


or

vmnames=$(/usr/bin/su ${vmuser} -c "/usr/local/lib/virtualbox/VBoxManage list vms" | awk -F '"' '{[B]ORS="";print[/B] $2}')
 
Back
Top