Mysteries of the unix kind

thats all folks
flickr / Paul (Creative Commons BY or BY-SA)

Sometimes, the simplest command line challenges can leave you leaning over your keyboard with that "What just happened?" look on your face. There's (almost) always a good explanation, but it might take a little head scratching before the "Aha!" comes along.

Here's one. We try to display a greeting with great enthusiasm and, instead, run headlong into an "event not found" error. The "event" in this case might not be immediately obvious, but the inclusion of the excalamation point in our echo statement is nudging bash to go looking into our command history for some previously entered command to run. Since the exclamation point isn't followed by a number, it can't identify the command it imagines we mean to refer to and gives us the "event (prior command) not found" error instead.

$ echo "Hello, World!"
-bash: !": event not found

The way around this problem is to use single quotes instead of double quotes. When we do that, bash will not try to interpret anything inside our quotes.

$ echo 'Hello, World!'
Hello, World!

The "event" that bash is trying to insert when you use double quotes is not the output of some command you previously ran, but the command itself. If the 9th command in our history queue was echo 'World!', the command echo Hello, !9 would yield Hello, echo World!. Why? Because using strings such a !9 just inserts previously entered commands into the command line. What happens next depends on the context those commands are dropped into. If they're inserted at the beginning of the line, they're run as commands. After all, that's what bash does whenever it sees text at the beginning of the command line. If they're entered after an echo command, they get echoed. Even the "echo" gets echoed.

Good thing we have single quotes to help us work around quandaries such as this. The water gets a little muddier, however, when you want to display a slightly more complicated simple statement. Entering "That's all, folks!" will, once again, leave bash complaining that it cannot find the elusive "event". But what have we here? We run into the same problem when we use single quotes.

$ echo "That's all, folks!"
-bash: !": event not found
$ echo 'That's all, folks!'
-bash: !': event not found

Something slightly different is going on here. In this case, the single quote at the end of the string isn't saving us because the quote preceding "That" is matched after "That". So, once again, the ! is standing out in the open for bash to pick up as an indicator that we are referring to a previously entered command.

To get around this problem and still display That's all, folks!, we can use two different sets of quotes -- double quotes to surround the first part of our statement and protect the apostrophe in That's from being taken too seriously and single quotes to prevent our exclamation point from kicking bash off into doing a historical search. Our new echo statement would look like this:

$ echo "That's all," 'folks!'
That's all, folks!

That's all, folks!

Join the Network World communities on Facebook and LinkedIn to comment on topics that are top of mind.

Copyright © 2014 IDG Communications, Inc.