home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Unix Power ToolsUnix Power ToolsSearch this book

27.12. Bourne Shell Quoting

I can't understand why some people see Bourne shell quoting as a scary, mysterious set of many rules. Quoting on Bourne-type shells is simple. (C shell quoting is slightly more complicated. See Section 27.13.)

The overall idea is this: quoting turns off (disables) the special meaning of characters. There are three quoting characters: single quote ('), double quote ("), and backslash (\). Note that a backquote (`) is not a quoting character -- it does command substitution (Section 28.14).

27.12.2. How Quoting Works

Table 27-1 summarizes the rules; you might want to look back at it while you read the examples.

Table 27-1. Bourne shell quoting characters

Quoting character

Explanation

'xxx'

Disable all special characters in xxx.

"xxx"

Disable all special characters in xxx except $, ', and \.

\x

Disable the special meaning of character x. At end of line, a \ removes the newline character (continues line).

To understand which characters will be quoted, imagine this: the Bourne shell reads what you type at a prompt, or the lines in a shell script, character by character from first to last. (It's actually more complicated than that, but not for the purposes of quoting.)

When the shell reads one of the three quoting characters, it does the following:

You also need to know how many characters will be quoted. The next few sections have examples to demonstrate those rules. Try typing the examples at a Bourne shell prompt, if you'd like. (Don't use C shell; it's different (Section 27.13).) If you need to start a Bourne-type shell, type sh; type exit when you're done.

In the previous example, what would happen if you put the $ inside the single quotes? (Single quotes turn off the meaning of $, remember.) Would the shell still expand $$ to its value? Yes, it would: the single quotes have lost their special meaning, so they don't affect any characters between them:

$ echo "What's next?  How many $$ did Mike's friend bring?"
What's next?  How many 18437 did Mike's friend bring?

How can you make both the $$ and the single quotes print literally? The easiest way is with a backslash, which still works inside double quotes:

$ echo "What's next?  How many \$\$ did Mike's friend bring?"
What's next?  How many $$ did Mike's friend bring?

Here's another way to solve the problem. A careful look at this will show a lot about shell quoting:

$ echo "What's next?  How many "'$$'" did Mike's friend bring?"
What's next?  How many $$ did Mike's friend bring?

To read that example, remember that a double quote quotes characters until the next double quote is found. The same is true for single quotes. So, the string What's next? How many (including the space at the end) is inside a pair of double quotes. The $$ is inside a pair of single quotes. The rest of the line is inside another pair of double quotes. Both of the double-quoted strings contain a single quote; the double quotes turn off its special meaning and the single quote is printed literally.

27.12.4. Multiline Quoting

Once you type a single quote or double quote, everything is quoted. The quoting can stretch across many lines. (The C shell doesn't work this way.)

For example, in the short script shown in Figure 27-1, you might think that the $1 is inside quotes, but it isn't.

Figure 27-1

Figure 27-1. Matching quotes

Actually, all argument text except $1 is in quotes. The gray shaded area shows the quoted parts. So $1 is expanded by the Bourne shell, not by awk.

Here's another example. Let's store a shell variable (Section 35.9) with a multiline message, the kind that might be used in a shell program. A shell variable must be stored as a single argument; any argument separators (spaces, etc.) must be quoted. Inside double quotes, $ and ' are interpreted (before the variable is stored, by the way). The opening double quote isn't closed by the end of the first line; the Bourne shell prints secondary prompts (Section 28.12) (>) until all quotes are closed:

$ greeting="Hi, $USER.
> The date and time now
> are:  `date`."
$ echo "$greeting"
Hi, jerry.
The date and time now
are:  Fri Sep  1 13:48:12 EDT 2000.
$ echo $greeting
Hi, jerry. The date and time now are: Fri Sep 1 13:48:12 EDT 2000.
$

The first echo command line uses double quotes, so the shell variable is expanded, but the shell doesn't use the spaces and newlines in the variable as argument separators. (Look at the extra spaces after the word are:.) The second echo doesn't use double quotes. The spaces and newlines are treated as argument separators; the shell passes 14 arguments to echo, which prints them with single spaces between.

A backslash has a quirk you should know about. If you use it outside quotes, at the end of a line (just before the newline), the newline will be deleted. Inside single quotes, though, a backslash at the end of a line is copied as is. Here are examples. I've numbered the prompts (1$, 2$, and so on):

1$ echo "a long long long long long long
> line or two"
a long long long long long long
line or two
2$ echo a long long long long long long\
> line
a long long long long long longline
3$ echo a long long long long long long \
> line
a long long long long long long line
4$ echo "a long long long long long long\
> line"
a long long long long long longline
5$ echo 'a long long long long long long\
> line'
a long long long long long long\
line

You've seen an example like example 1 before. The newline is in quotes, so it isn't an argument separator; echo prints it with the rest of the (single, two-line) argument. In example 2, the backslash before the newline tells the shell to delete the newline; the words long and line are passed to echo as one argument. Example 3 is usually what you want when you're typing long lists of command-line arguments: Type a space (an argument separator) before the backslash and newline. In example 4, the backslash inside the double quotes is ignored (compare to example 1). Inside single quotes, as in example 5, the backslash has no special meaning; it's passed on to echo.

-- JP



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.