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.:Then press enter.
To remove the
$vm
variable, use:unset vm