Mac OS X Reference Library Apple Developer
Search

Historical Footnotes and Arcana

This appendix contains historical footnotes extracted from elsewhere in the document to improve readability. They appear in this appendix because although they may be of some interest, they are not critical to a general understanding of the subject.

Historical String Parsing

In some early Bourne-compatible shells, the second statement below does not do what you might initially suspect:

STRING1="This is a test"
STRING2=$STRING1

Most modern Bourne shells parse the right side of the assignment statement first (including any splitting on spaces), then expand the variable $STRING1, thus copying the complete value of STRING1 into STRING2.

Note: This pre-splitting behavior is specific to the right side of assignment statements. All other statements are split after variables are expanded.

Some older shells, however, may do the space splitting after expanding the variable. Such shells interpret the second statement as though you had typed the following:

STRING2=This is a test

as a two-part statement: an assignment statement (FIRST_ARGUMENT=This) followed by a command (is) with two arguments (a and test).

Because there is no semicolon between the assignment and the command, the shell treats this assignment statement as an attempt to modify the environment passed to the is command (a technique described in “Overriding Environment Variables for Child Processes (Bourne Shell)”). This is clearly not what you intended to do.

For maximum compatibility, you should always write such assignment statements like this:

STRING1="This is a test"
STRING2="$STRING1"

In any Bourne shell, this is interpreted correctly as:

STRING2="This is a test"

Compatibility Note: This behavior was first introduced by zsh because this was a common programmer mistake that caused errors.

When run as /bin/sh, some early versions of zsh emulate the previous Bourne shell behavior for compatibility. Thus, in a script that starts with #!/bin/sh, the statement may fail if sh is really zsh.

Current versions of zsh obey the modern splitting rules even when run as /bin/sh.

Similarly, in modern shells, quotation marks and other special characters are parsed before expansion. Thus, quotation marks inside a variable do not affect the splitting behavior. For example:

FOO="\"this is\" a test"
ls $FOO

is equivalent to:

ls \"this
ls is\"
ls a
ls test

In older Bourne shells, however, this may be misinterpreted as:

ls "this is"
ls a
ls test

In general, it is not worth the effort to support shells with this broken splitting behavior, and it is unlikely that you will encounter them; the modern splitting behavior has been common since the mid-1990s.




Last updated: 2010-06-18

Did this document help you? Yes It's good, but... Not helpful...