2

How can you set the output of a command run in terminal to a variable after it has run?


Background

(You can skip of you don't need the background) I run VirtualBox VM and do a lot from the command line, especially when I am remote. VBoxManage requires either a UUID or the name of the virtual machine in order to interact with it. For instance, if I wanted to power off a VM, the syntax would be (I have an alias set for VBoxManage as vbm):

vbm controlvm <vmname>|<UUID> poweroff

This is pretty easy if you have VM names that don't have spaces or special characters in them like "Client X Web Dev Server". I do this so I can take advantage of descriptive names. So, the tradeoff is that I use the UUID. To do this, I created another alias that will `cut' the output down to just the UUID. For example, if I am looking for my "Fred Web Dev Server" (I am a fan of the Flintstones), I execute the command:

vbm list vms

My output is as follows (shortened list):

"Fred - FreeBSD 10.2" {f93c17ca-ab1b-4ba2-95e5-a1b0c8d70d2a}
"FreeBSD 10.2 Master" {ae2a2d61-25e5-4b5e-b455-1b2f60b49157}
"Windows 7 Pro VL" {62bfbca1-9fb4-4758-aeac-2777f2614ffd}
"Windows 10 Pro" {46b285c3-cabd-4fbb-92fe-c7940e0c6a3f}

So, to interact with "Fred" I just issue the command:

vbm list vms | grep Fred

and as expected, I get:

"Fred - FreeBSD 10.2" {f93c17ca-ab1b-4ba2-95e5-a1b0c8d70d2a}

I then pipe it to another alias, vmc, that issues a "nested" cut command: cut -f 2 -d { | cut -f 1 -d }. My result is just the UUID without brackets

$ vbm list vms | grep Fred | vmc
f93c17ca-ab1b-4ba2-95e5-a1b0c8d70d2a

What I would like to do is set that result to a variable. What I have been doing is re-executing the command, but editing it first to add a variable set instruction at the beginning like this:

$ set vm=`vbm list vms | grep Fred | vmc`

Then I can reuse vm in my commands easily:

$ vbm control $vm poweroff

I like having the option of not setting the variable because there are times I don't need to use it, just see it. I can redirect it, but that goes to a file. I have tried to pipe it, but that requires another command. Does anyone know how to do this?


Update (5/20/16):

I got much more out of this question than I expect to so thanks to @user3439894, @fd0 and @Mateusz Szlosek for their excellent suggestion.

I selected @user3439894' solution of using

vm=`!!` 

because it was simple and elegant. I assigned it to a shortcut key for when I needed it for even easier use. However just reading the other answers, I now have some others solutions I can use for different scripting challenges I have run into the past.

  • 2
    After you've executed vbm list vms | grep Fred | vmc, and you want to immediately set the output of that commend to a variable, just type, e.g. vm=`!!` and press enter. To remove the $vm variable, use: unset vm – user3439894 May 18 '16 at 16:51
  • @user3439894 You should add that as an answer so I can upvote. – Allan May 18 '16 at 17:07
2

One way is to accomplish what you're asking is:

After you've executed vbm list vms | grep Fred | vmc, and you want to immediately set the output of that commend to a variable, just type, e.g.:

vm=`!!`

Then press enter.

To remove the $vm variable, use: unset vm

2

What if you used a function defined in one of your bash startup file?

getvmid () {
/Applications/VirtualBox.app/Contents/MacOS/VBoxManage list vms | grep $1 | cut -f 2 -d { | cut -f 1 -d }
}

The $1 is the first parameter of the function. It also limits the scope of the variable.

getvmid Fred

Setting the variable:

vm=$(getvmid Fred)

Untested but this should also work:

vbm control "$(getvmid Fred)" poweroff
  • I like this. It never dawned on me that I could put functions in my bash startup file. I will have to research this more. – Allan May 18 '16 at 17:18
1

You can pipe the output from vmc to the xargs command line tool.

This will look like:

vbm list vms | grep Fred | vmc | xargs -I {} vbm control {} poweroff

You'll avoid assigning the output to the variable.

  • That a good suggestion, but I usually want to reuse the same uuid for the next set of commands, like vbm modify $vm --vrde on or similar.... – Allan May 18 '16 at 18:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .