Online Book Reader

Home Category

Classic Shell Scripting - Arnold Robbins [94]

By Root 909 0
on the shell's syntax. Most importantly, the I/O redirection > out is recognized and saved for later. Processing continues with this line, where the extent of each token is as shown on the line below the command:echo ~+/${f}[12] $y $(echo cmd subst) $((3 + 2))

| 1| |--- 2 ---| 3 |------ 4 ------| |-- 5 ---|

The first word (echo) is checked to see if it's a keyword, such as if or for. In this case it's not, so processing continues with the line unchanged.

The first word (still echo) is checked to see if it's an alias. It isn't, so processing continues with the line still unchanged.

All words are scanned for tilde expansion. In this case, ~+ is a ksh93 and bash extension which is equivalent to $PWD, the name of the current directory. (This is described in Section 14.3.7.) Token 2 is modified, and processing continues with this:echo /tmp/x/${f}[12] $y $(echo cmd subst) $((3 + 2))

| 1| |----- 2 -----| 3 |------ 4 ------| |-- 5 ---|

The next step is variable expansion: tokens 2 and 3 are modified. This produces:echo /tmp/x/f[12] a b $(echo cmd subst) $((3 + 2))

| 1| |---- 2 ---| |3| |------ 4 ------| |-- 5 ---|

Command substitutions are processed next. Note that this can recursively invoke all the steps in the list! In this case, since we're trying to keep things easy to follow, command substitution modifies token 4, producing:echo /tmp/x/f[12] a b cmd subst $((3 + 2))

| 1| |---- 2 ---| |3| |-- 4 --| |-- 5 ---|

Arithmetic substitution is now performed. Token 5 is modified, and the result is:echo /tmp/x/f[12] a b cmd subst 5

| 1| |---- 2 ---| |3| |-- 4 --| 5

The results of all the previous expansions are rescanned for the characters in $IFS. If found, they act as separators, creating additional words. For example, the two characters $y made up one word originally, but the expansion a-space-b is split at this stage into two words, a and b. The same applies for the results of the command substitution, $(echo cmd subst). The previous token 3 becomes tokens 3 and 4, and the previous token 4 becomes tokens 5 and 6. The result is:echo /tmp/x/f[12] a b cmd subst 5

| 1| |---- 2 ---| 3 4 |5| | 6 | 7

The last substitution stage is wildcard expansion. Token 2 becomes tokens 2 and 3. The result is:echo /tmp/x/f1 /tmp/x/f2 a b cmd subst 5

| 1| |-- 2 --| |-- 3 --| 4 5 6 | 7 | 8

The shell is now ready to run the final command. It looks up echo. It happens that in both ksh93 and bash the echo command is built into the shell.

The shell actually runs the command. It first performs the > out I/O redirection, and then calls its internal version of echo to print out the final arguments.

Here is the final result:

$ cat out

/tmp/x/f1 /tmp/x/f2 a b cmd subst 5

The eval Statement

The eval statement tells the shell to take eval's arguments and run them through the command-line processing steps all over again. Here is an example to help you understand the implications of eval.

eval ls passes the string ls to the shell to execute, so the shell prints a list of files in the current directory. This example is simplistic: nothing about the string ls needs to be sent through the command-processing steps twice. However, consider this:

listpage="ls | more"

$listpage

Instead of producing a paginated file listing, the shell treats | and more as arguments to ls, and ls complains that no files of those names exist. Why? Because the pipe character appears in step 5 when the shell evaluates the variable, after it has actually looked for pipe characters (in step 1). The variable's expansion isn't even parsed until step 8. As a result, the shell treats | and more as arguments to ls so that ls tries to find files called | and more in the current directory!

Now consider eval $listpage instead of just $listpage. When the shell gets to the last step, it runs the command eval with arguments ls, |, and more. This causes the shell to go back to step 1 with a line that consists of these arguments. It finds | in step 1 and splits the line into two commands, ls and more. Each command is processed in the normal

Return Main Page Previous Page Next Page

®Online Book Reader