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:
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:
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):
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.
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
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.