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.
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 |
After upgrading to DYNIX/ptx V4.6, you may need to address the following issues:
If an entry for a user account in /etc/passwd specifies /bin/sh as the default shell program, the user will get the Korn shell under V4.6. If you want the user to continue using the Bourne shell, change the entry to /bin/bsh.
In the V4.6 Korn shell, the ENV environment variable applies only to interactive shells.
When the Korn shell is invoked interactively, it reads the startup file mentioned in the ENV environment variable (typically a file such as ~/.kshrc) before executing a script. This can cause local definitions of commands to be used instead of the DYNIX/ptx V4.6 versions. To disable this feature, add -p to the interpreter line in the script:
#!/bin/ksh -p
When -p is specified, the shell reads the startup script /etc/suid_profile before executing the script.
When a child process died with a signal, the V4.4/V4.5 shell would exit normally with an exit status of signal number + 128. The Korn shell now exits with the same signal that killed the child. In other words, the behavior of a program that dies with a signal is identical to a script that dies with a signal.
Korn shell scripts may need to be converted to use the new version of the shell. See "Convert Korn Shell Scripts" for more information.
Scripts that do not specify a shell program with the #! interpreter line will be executed with the Korn shell. These scripts were previously executed with the Bourne shell. If you want the scripts to continue to use the Bourne shell, add this interpreter line to the scripts:
#! /bin/bsh
Otherwise, convert the scripts as necessary for the Korn shell.
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.
You will need to address the following problems when converting old /bin/ksh scripts to the new version of ksh.
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.
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.
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.
The typeset -s option does not exist in the new Korn shell. Replace this option with -L.
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.
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 quick solution is to comment out line 7, making variable a global. However, the global could then be stepped on or other problems could be encountered.
The better solution is to define assign with the older style definition so that it shares the caller's scope:
assign () { ...
When doing this, be aware that the typeset on line 2 now affects the caller's scope, adding the variables left and right to do_it's scope.
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:
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.
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
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.
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 ]).
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.
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.
The shell now supports floating-point arithmetic. The typeset command has two new options to handle floating-point arithmetic:
The following C operators have been added:
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.
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'
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:
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.
The following changes apply to parameters:
A parameter is a variable, one or more digits, or any of the characters *, @, #, ?, -, $, and !. A variable is denoted by a vname. To create a variable whose vname contains a ., a variable whose vname consists of everything before the last . must already exist. A variable has a value and zero or more attributes.
The shell supports both indexed and associative arrays. An element of an array variable is referenced by a subscript. The range of values for subscripts is now 0 through 4095.
Name references are now supported.
In addition to the vname=value [ vname=value ] . . . syntax, the value of a variable can also be assigned with this syntax:
vname[subscript]=value [ vname[subscript]=value ] ...
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.
The following new variables are set automatically.
The following variables have been changed:
The ERRNO variable is now obsolete. Most error messages now provide a reason for the failure.
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).
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.
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 |
xdigit |
|
digit |
punct |
The following vi edit commands have been added:
The following conditional expressions have been added:
The exclamation mark (!) is now a reserved word and negates the return value of an expression.
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).
Commands now terminate with one of the following values:
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.
All built-in commands now include the -? option, which displays a usage message.
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.