Online Book Reader

Home Category

Classic Shell Scripting - Arnold Robbins [202]

By Root 1036 0
shows how to save the shell's state into a file. An apparent oversight in the POSIX standard is that there's no defined way to save function definitions for later restoration! The example shows how to do that for both bash and ksh93.

Example 14-1. Saving shell state, indcluding functions, for bash and ksh93

{

set +o Option settings

(shopt -p) 2>/dev/null bash-specific options, subshell silences ksh

set Variables and values

export -p Exported variables

readonly -p Read-only variables

trap Trap settings

typeset -f Function definitions (not POSIX)

} > /tmp/shell.state

Note that bash and ksh93 can use different syntaxes for defining functions, so care is required if you wish to dump the state from one shell and restore it in the other!

echo is not portable

As described in Section 2.5.3, the echo command may only be used portably for the simplest of uses, and various options and/or escape sequences may or may not be available (the POSIX standard notwithstanding).

In ksh93, the built-in version of echo attempts to emulate whatever external version of echo would be found in $PATH. The reason behind this is compatibility: on any given Unix system, when the Korn shell executes a Bourne shell script for that system, it should behave identically to the original Bourne shell.

In bash, on the other hand, the built-in version behaves the same across Unix systems. The rationale is consistency: a bash script should behave the same, no matter what Unix variant it's running on. Thus, for complete portability, echo should be avoided, and printf is still the best bet.

OPTIND can be a local variable

In Section 6.4.4, we described the getopts command and the OPTIND and OPTARGS variables. ksh93 gives functions defined with the function keyword a local copy of OPTIND. The idea is that functions can be much more like separate scripts, using getopts to process their arguments in the same way a script does, without affecting the parent's option processing.

${ var :? message } may not exit

The ${ variable :? message } variable expansion checks if variable is set. If it isn't, the shell prints message and exits. However, when the shell is interactive, the behavior varies, since it's not always correct for an interactive shell to just blindly exit, possibly logging the user out. Given the following script, named x.sh:

echo ${somevar:?somevar is not set}

echo still running

bash and ksh93 show the behaviors listed in Table 14-1.

Table 14-1. Interactivity of ${var:?message} in bash and ksh93

Command

Message printed

Subsequent command run

$ bash x.sh

Yes

No

$ ksh93 x.sh

Yes

No

bash$ . x.sh

Yes

Yes

ksh93$ . x.sh

Yes

No

This implies that if you know that a script will be executed with the dot command, you should ensure that it exits after using the ${ variable :? message } construct.

Missing loop items in a for loop

Here's a subtle point. Consider a loop such as:

for i in $a $b $c

do

do something

done

If all three variables are empty, there are no values to loop over, so the shell silently does nothing. It's as if the loop had been written:

for i in # nothing!

do

do something

done

However, for most versions of the Bourne shell, actually writing a for loop that way would produce a syntax error. The 2001 POSIX standard made an empty loop valid when entered directly.

The current versions of both ksh93 and bash accept an empty for loop as just shown, and silently do nothing. As this is a recent feature, older versions of both shells, as well as the original Bourne shell, are likely to produce an error message.

DEBUG traps behave differently

Both ksh88 and ksh93 provide a special DEBUG trap for shell debugging and tracing. In ksh88, the traps on DEBUG happen after each command is executed. In ksh93, the DEBUG trap happens before each command. So far so good. More confusing is that earlier versions of bash follow the ksh88 behavior, whereas the current versions follow that of ksh93. This is illustrated in Section 13.3.2.

Long and short options

Return Main Page Previous Page Next Page

®Online Book Reader