MacOS – Set the result of command to variable in Terminal post execution

bashmacosterminalvirtualbox

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.

Best Answer

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