I have a simple bash shell script which is driving me bonkers. All I want to do is run a command which returns a result which I will then use in another command. The result of the first command returns a location on my hard drive with spaces. Here's what I have...

# Get list of virtual machines.  VMname will hold the address of the .vmx file
VMname=`./vmrun list`
echo $VMname

# Get list of snapshots
command="./vmrun listSnapshots "
echo $command

It looks like when I try to append the single quotes around the $VMname it only appends to the left, ie I only the left single quote is appended. Is there something silly I am doing wrong? This really is driving me crazy!

  • Don't forget to accept the answer you think best solves your problem. Do so by clicking the checkmark to the left of the answer. Welcome to the site! – amphetamachine Aug 26 '11 at 0:37

All you need is:

VMname=$(./vmrun list)
snapshotList=$(./vmrun listSnapshots "$VMname")

If you don't need the intermediate variable VMname, you can also use:

snapshotList=$(./vmrun listSnapshots "$(./vmrun list)")

Use $() instead of `` (unless you're using a very old shell that doesn't understand the former). Nesting of $() constructions is easier.

  • Quotes? .. something="$(. . .)" – Peter.O Aug 24 '11 at 13:12
  • 2
    @fred. Useless, no word-splitting is performed during variable assignation. – Stéphane Gimenez Aug 24 '11 at 13:17
  • @fred, as Stéphane says, they're not needed for assignment, but on the other hand they won't hurt. I learned this lesson just recently. – glenn jackman Aug 24 '11 at 14:17
  • 1
    @glennjackman: Actually they CAN hurt as fred just recently found out: Why does the exclamation mark ! sometimes upset bash?. The thing is to understand when to use them and when not to. – Caleb Aug 24 '11 at 21:41
  • 1
    @fred Lesson 1 is to always put the quotes. Lesson 2 is what happens without them and how it can occasionally be useful. Lesson 3 is that assignments and case expressions have implicit double quotes already, e.g. foo=$(bar) means the same as foo="$(bar)" (the reason is that these contexts allow a single word, so word splitting wouldn't make sense). Note that this does not extend to export foo="$(bar)". – Gilles Aug 24 '11 at 22:07

Just use proper quoting and string security.

You could even simplify it a little and shore up the quoting by not executing variables:

# Get list of virtual machines.  VMname will hold the address of the .vmx file
VMname="$(./vmrun list)"
echo "$VMname"

# Get list of snapshots
echo "./vmrun listSnapshots '$VMname'"
snapshotList="$(./vmrun listsnapshots "$VMName")"
  • Markdown messed up the highlighting, but I assure you, that's proper shell syntax. – amphetamachine Aug 24 '11 at 12:07
  • You can specify the language for markdown: meta.stackexchange.com/questions/78363/… – glenn jackman Aug 24 '11 at 13:12
  • @glenn: no effect – amphetamachine Aug 24 '11 at 14:13
  • 1
    @amphetamachine: It's just not smart enough to deal with that kind of nesting. Best to turn it off in these cases where it gets things wrong and thus confuses the issue rather than clarifying it. – Caleb Aug 24 '11 at 21:43

Oh boy. Why not just write this?

command="./vmrun listSnapshots '$VMname'"

  • I tried that, but after pulling my hair out I think I have found the answer to the problem... I looks like when I run the command vmrun list, it adds a weird unprintable character to the end that is acting like a carrage return, when I then add the second single quote to the end, it begins to write on the same line. I have no idea why. I am now piping ./vmrun list into | tail -1 | sed 's/[^a-zA-Z0-9\. ]//g' and it seems to get rid of it... Thanks for replying though!! – BON Aug 24 '11 at 9:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.