DYNIX/ptx V4.6.0 Release Notes: Shell Changes and Conversion


Appendix A
Shell Changes and Conversion


Shell Programs

In DYNIX/ptx V4.6, the default shell program is the UNIX98 shell. This shell is similar to the 1993 release of the Korn shell and can be invoked as /bin/sh, /bin/ksh, or /bin/ksh93. The shell programs provided with DYNIX/ptx V4.4/V4.5 are still available; however the Bourne shell and and the older version of the Korn shell must be invoked differently.

Table A-1. Shell Invocation

Shell Program

DYNIX/ptx V4.4/V4.5

DYNIX/ptx V4.6

UNIX98

NA

/bin/sh, /bin/ksh, or /bin/ksh93

Bourne

/bin/sh

/bin/bsh

Revised Korn 1998

/bin/ksh

/bin/ksh88e

Korn 1988

/bin/ksh88

/bin/ksh88

C

bin/csh

bin/csh



Shell Issues in V4.6

After upgrading to DYNIX/ptx V4.6, you may need to address the following issues:


Convert Korn Shell Scripts

Existing /bin/ksh scripts may encounter problems when run under DYNIXptx/V4.6. A new utility, convert_kscript, is available to assist you with converting these scripts.


/bin/ksh Problems

You will need to address the following problems when converting old /bin/ksh scripts to the new version of ksh.


Function Definition

Korn shell scripts use two forms of function definition:

In DYNIX/ptx V4.4/V4.5, these forms were equivalent and created a function with local scope. In the V4.6 Korn shell, only the second form creates a function with local scope. The first form creates a function that shares the caller's scope. This change is probably the biggest source of problems when converting shell scripts. Typically, the problem is seen with functions that call getopt to parse their arguments.

To correct this problem, all functions must be defined with the function name { ... form. You can use the convert_kscript utility to fix this and other conversion problems.


Quotation Marks

The new shell parses quotes more rigorously. A script containing errors may have run correctly with the DYNIX/ptx V4.4/V4.5 shell, but the V4.6 shell will detect those errors and cause the script to fail.


Changes to Commands

The shell's whence -v command now reports a different value for certain commands such as times and ulimit. If your scripts depend on a certain output, be sure to determine whether that output has changed.

Also review the section "Changed Commands" in Chapter 1 for changes to other operating system commands that may be included in your scripts.


Use of typeset -s

The typeset -s option does not exist in the new Korn shell. Replace this option with -L.


SIGCLD Behavior

SIGCLD is not disabled when processing a SIGCLD trap. If you trap SIGCLD (signaled when a child process changes state) and your trap code runs another process, the trap will be signaled again when that process exits. For example:

trap "rm $tempfile" CLD 

will continuously loop running rm $tempfile if a SIGCLD occurs. Each time rm $tempfile finishes, it triggers a new SIGCLD.


Scoping Difference

Functions defined by function name { ... inherit only the global scope. In the DYNIX/ptx V4.4/V4.5 Korn shell, functions inherited both the global scope and all variables typeset in the chain of caller functions. In the V4.6 shell, the caller's scope is strictly private and not visible to the callee. In other words, it acts more like C language scoping.

Consider the following script:


1:  function assign {
2:      typeset left=$1 right=$2
3       eval "$left='$right'"
4   } 5:
6   function do_it {
7       typeset a                   # "a" is in do_it's scope
8:
9       a="Private scope"           # set "a" in do_it's scope
10      assign a "Inherited scope"  # set "a" in assign's scope
11      echo $a                     # print "a" in do_it's scope
12: } 
13: a='Global scope'                # set "a" in the global scope
14: do_it 
15: echo "Global value = $a"        # print "a" in the global scope

The function assign assigns its second argument to the value of its first argument in the scope of assign. The function do_it provides another layer of scope. Line 9 sets the value of variable a in do_it's scope and line 10 indirectly sets variable a in assign's scope. Line 11 prints the value of a in do_it's scope, and line 15 prints the value of a in the global scope.

In DYNIX/ptx V4.4/V4.5, assign inherits do_it's scope. The eval on line 3 expands to a='Inherited scope', with variable a inherited from do_it. This produces the following output:

Inherited scope
Global value = Global scope

In the V4.6 shell, the scopes of assign and do_it are separate. The eval on line 3 expands the same a='Inherited scope', but since do_it's scope is not inherited, the variable a is a global reference. This produces the following output:

Private scope
Global value = Inherited scope

Converting a script that relies on inherited scope is not a mechanical process. It requires that you understand what the function is trying to do so that you can chose the appropriate fix. Here are some possibilities:


The convert_kscript Utility

A new utility, convert_kscript, can be used to convert function definitions, optionally add the -p flag to the interpreter line, and check for other conversion problems. The utility has this syntax:

convert_kscript [-pknsoqq] [-S shellpath] files..
convert_kscript [-cpknsoqq] [-S shellpath] [infile [outfile]]

The options are as follows:

-p
Add -p to the interpreter line.
-k
Ignore errors (similar to the -k option to make).
-c
Process infile to outfile, instead of converting files in place.
-n
Check files without actually changing them.
-s
Treat /bin/sh scripts as ksh scripts. (Edited scripts will not run with the Bourne Shell again because the function change is not backward compatible.)
-o
Process obsolete constructs. This option shows the changes that are necessary to update a script to the new shell; however, it does not make the changes.
-S
Use shellpath as the UNIX98-compatible shell for checking.
-q
Be somewhat quieter; reports only real changes and errors. Warnings and questionable changes are not reported.
-qq
Be very quiet. This option is not intended for normal use because it does not report changes that you need to make by hand.

By default, convert_kscript converts each file in place, leaving the original script in file.OLD. It also reports changes that must be made by hand. It requires a copy of /bin/sh in your path, or you can use -S shellpath to point to a usable shell. We recommend that you initially run convert_kscript with the -n option to identify the changes that the utility can perform without actually making them.


New Features and Changes in the Korn Shell

The Korn shell program (/bin/sh) provided with DYNIX/ptx V4.6 contains several new features and implementation changes from the previous version of the shell. See the sh(1) man page for more information about these changes. We also recommend the following manual:

The New KornShell Command and Programming Language
Morris I. Bolsky and David G. Korn
ISBN 0-13-182700-6

Invocation

In DYNIX/ptx V4.4/V4.5, the Korn shell was invoked as ksh and the restricted shell was invoked as rksh. In DYNIX/ptx V4.6, the Korn shell is invoked as either sh or ksh and the restricted shell is invoked as rsh.


Associative Arrays

The shell now supports associative arrays. An associative array is created with the -A option to typeset. A subscript for an associative array is denoted by a string enclosed between brackets ([ and ]).


Name References

A name reference is a variable that is a reference to another variable. The typeset -n command creates a name reference. The value of the variable at the time of the typeset command becomes the variable that will be referenced whenever the name reference variable is used.


Discipline Functions

A function whose varname contains a period (.) is called a discipline function. The portion of the varname preceding the last period must refer to an existing variable.


Arithmetic

The shell now supports floating-point arithmetic. The typeset command has two new options to handle floating-point arithmetic:

-E
Determines the number of significant figures that will be used when the specified variable is expanded.
-F
Determines the number of places following the decimal point that will be used when the specified variable is expanded.

The following C operators have been added:

?:
conditional operator
,
comma operator
++
prefix operator
--
postfix operator
+
unary operator

Functions from the ANSI C math library can now be used in arithmetic expressions.

For integer constants, the shell now supports arithmetic bases up to base64.


Preset Aliases

The following aliases are preset:

autoload='typeset -fu'
command='command'
fc=hist
float='typeset -E'
functions='typeset -f'
hash='alias -t - -'
history='hist -l'
integer='typeset -i'
nameref='typeset -n'
nohup='nohup '
r='hist -s'
redirect='command exec'
stop='kill -s STOP'
times='{ {time;} 2>&1;}'
type='whence -v'

Commands

The following command has been added:

for (( [ expr1 ] ; [ expr2 ] ; [ expr3 ] )) ;dolist ;done

The arithmetic expression expr1 is evaluated first. The arithmetic expression expr2 is repeatedly evaluated until it evaluates to zero. When it is non-zero, list is executed and the arithmetic expression expr3 is evaluated. If any expression is omitted, then it behaves as if it evaluated to 1.

The following commands have been modified:

function
A function whose varname contains a period (.) is called a discipline function. The portion of the varname preceding the last period must refer to an existing variable.

A function defined with the function varname syntax can also be used as an argument to the . special built-in command to get the equivalent behavior as if the function were defined with the varname() syntax.

time
The pipeline argument is now optional. If it is omitted, the shell prints the user and system time for the current shell and its children on standard error.

Parameters

The following changes apply to parameters:

vname[subscript]=value [ vname[subscript]=value ] ...

New Parameter Expansions

The following parameter expansions have been added:

${!vname}

Expands to the name of the variable referred to by vname. This will be vname unless vname is a name reference.

${!vname[subscript]}

Expands to the name of the subscript unless subscript is * or @. When subscript is *, the list of array subscripts for vname is generated. For a variable that is not an array, the value is 0 if the variable is set; otherwise it is null. When subscript is @, the action is the same, except that when double quotes are used, each array subscript yields a separate argument.

${!prefix*}

Expands to the names of the variables whose names begin with prefix.

${parameter:offset:length} or ${parameter:offset}

Expands to the portion of the value of parameter starting at the character determined by expanding offset as an arithmetic expression. The expansion contains the number of characters in the arithmetic expression defined by length. In the second form, the remainder of the value is used. If parameter is * or @, or is an array name indexed by * or @, then offset and length refer to the array index and number of elements respectively.

${parameter/pattern/string} or ${parameter//pattern/string}

Expands parameter and replaces pattern with the given string. In the first form, only the first occurrence of pattern is replaced. In the second form, each match for pattern is replaced by the given string. When string is null, the pattern will be deleted and the / in front of string may be omitted. When parameter is @, *, or an array variable with subscript @ or *, the substitution operation is applied to each element in turn.


New Shell Variables

The following new variables are set automatically.

.sh.edchar
The value of the keyboard character(s) entered when the shell is processing a KEYBD trap. If the value is changed as part of the trap action, then the new value replaces the key (or key sequence) that caused the trap.
.sh.edcol
The character position of the cursor at the time of the most recent KEYBD trap.
.sh.edmode
Set to ESC when the shell is processing a KEYBD trap while in vi insert mode. Otherwise, .sh.edmode is null when the shell is processing a KEYBD trap.
.sh.edtext
The characters in the input buffer at the time of the most recent KEYBD trap. The value is null when the shell is not processing a KEYBD trap.
.sh.name
Set to the name of the variable when a set or get discipline is invoked.
.sh.subscript
Set to the name subscript of the variable when a set or get discipline is invoked.
.sh.value
Set to the value of the variable at the time of a set discipline.
.sh.version
Set to a value that identifies the version of this shell.
FIGNORE
A pattern that defines the set of filenames to be ignored when the shell is performing filename matching.
HISTEDIT
The name of the editor for the hist command.
NLSPATH
The location of message catalogs for the processing of LC_MESSAGES.

Changes to Shell Variables

The following variables have been changed:

ENV
Now used only with interactive shells.
SECONDS
Now has a granularity of milliseconds instead of seconds.
TMOUT
Now sets the timeout for the select command.

Obsolete Shell Variable

The ERRNO variable is now obsolete. Most error messages now provide a reason for the failure.


Quoting

The shell now processes a single quoted string preceded by an unquoted $ as an ANSI-C string, except that \0 within the string causes the remainder of the string to be ignored and \E is equivalent to the escape characer (ascii 033).


Functions

function has been revised as follows:

function varname { list ;} 
varname () { list ;}

This syntax defines a function referenced by varname. A function whose varname contains a period (.) is called a discipline function; the portion of the varname preceding the last . must refer to an existing variable. The body of the function is the list of commands between { and }. A function defined with the function varname syntax can also be used as an argument to the . special built-in command to get the equivalent behavior as if the varname() syntax were used to define it.


Pattern Matching

Character classes can now be specified with the following syntax:

 [:class:]

class can be one of the following:

alnum

graph

space

alpha

lower

upper

cntrl

print

xdigit

digit

punct



vi Edit Changes

The following vi edit commands have been added:

eof
When the EOF character (usually Ctrl-D) appears as the first character on a line, it causes the shell to terminate if the ignoreeof option is not set. If the ignoreeof option is set, this character is ignored.
[count]space
Moves the cursor forward one character.
[line_number]v
Returns the command hist -e ${VISUAL:-${EDITOR:-vi}} line_number in the input buffer. If line_number is omitted, then the current line is used.

Conditional Expressions

The following conditional expressions have been added:

string
True, if string is not null.
string == pattern
True, if string matches pattern. Any part of pattern can be quoted to cause it to be matched as a string.

New Compound Commands

The exclamation mark (!) is now a reserved word and negates the return value of an expression.


Path Searches

If the shell determines that there is a built-in version of a command corresponding to a given pathname, it invokes the built-in in the current process. Otherwise, the shell creates a process and attempts to execute the command via exec(2).


Return Values for Commands

Commands now terminate with one of the following values:

0-125
The command terminated normally.
126
The command was found but was not executable.
127
The command was not found.
256+sig_num
The command terminated abnormally. You can obtain the name of the signal with the -l$? option to the built-in kill utility.

Traps

A new KEYBD trap is available to allow you to bind editing keys. It intercepts keys as they are typed and changes the characters that are actually seen by the shell.

The shell now executes the DEBUG trap before each command.


Built-In Commands

All built-in commands now include the -? option, which displays a usage message.


New Commands

disown
Prevents jobs from being sent a HUP signal by the login shell.
false
Returns the value "false." This command was previously an alias.
hist
Equivalent to the fc command provided with earlier versions of the Korn shell. fc is now an alias.
printf
Similar to the ANSI C printf function.
sleep
Suspends execution for the specified number of decimal seconds or fractions of a second.
true
Returns the value "true." This command was previously an alias.

Changes to Commands

alias
New -p option prints the word alias before each alias in the output. The -x option is now obsolete and has no effect.
cd
The -L and -P options are now documented. -L, the default, prevents symbolic links from being expanded when PWD is set. -P causes the symbolic links to be expanded.
command
Functions are no longer included in the search order for the specified name. If name is a special built-in command, it is treated as a regular built-in command.
exec
New options: -a name specifies the name of the first argument; -c causes the environment to be cleared before applying variable assignments associated with the exec invocation.
fc
This command has been replaced by the hist command; however, it is still available as a built-in alias.
kill
The command now sends two signals to a process: the signal that you specified, followed by a SIGCONT to restart the process in case it is stopped.
print
The -f option causes arguments to be printed in the same manner as printf.
pwd
The -L and -P options are now documented. If -L is specifed, symbolic links in the directory pathname are not expanded. With -P, symbolic links are expanded.
read
New options: -A unsets the variable vname and stores each field that is read in successive elements of the indexed array vname. -d delim changes the terminating character from newline to the first character of delim. -t specifies a timeout in integer seconds when reading from a terminal or pipe.
set
New options: -P causes the cd and pwd built-in commands to default to physical mode; -o privileged is the same as -p; -o physical is the same as -P; -p disables processing of $HOME/.profile and uses /etc/suid_profile instead of the file specified by ENV.
times
This command is now obsolete; however, it is still available as a built-in alias.
trap
New -p option causes the trap action associated with each trap to be printed with appropriate quoting. If sig is DEBUG, the action is now executed before each command. If sig is KEYBD, the action is executed whenever a key is read while in emacs, gmacs, or vi mode.
typeset
New options: -A declares vname to be an associate array; -n declares vname to be a reference to the variable whose name is defined by the value of variable vname; -E and -F declare vname to be a double precision floating point number. With -E, if n is non-zero it defines the number of significant figures that are used when expanding vname; otherwise 10 significant figures are used. With -F, if n is non-zero it defines the number of places after the decimal point that are used when expanding vname; otherwise 10 places after the decimal point are used.

The new -p option causes typeset (followed by the option letters) to be printed before each name rather than the names of the options. If any option other than -p is given, only those variables having all of the given options are printed.

ulimit
New options: -a lists all of the current resource limits; -m specifies the number of KB on the size of physical memory.
whence
New -a option causes all interpretations of the given name to be reported. The output from whence has changed; see sh(1) for details.