Enhanced Korn shell (ksh93)

In addition to the default system Korn shell (/usr/bin/ksh), AIX® provides an enhanced version available as Korn shell /usr/bin/ksh93. This enhanced version is mostly upwardly compatible with the current default version, and includes a few additional features that are not available in Korn shell /usr/bin/ksh.

Some scripts might perform differently under Korn shell ksh93 than under the default shell because variable handling is somewhat different under the two shells.

Note: There is also a restricted version of the enhanced Korn shell available, called rksh93.

The following features are not available in Korn shell /usr/bin/ksh, but are available in Korn shell /usr/bin/ksh93:

Item Description
Arithmetic enhancements You can use libm functions (math functions typically found in the C programming language), within arithmetic expressions, such as $ value=$((sqrt(9))). More arithmetic operators are available, including the unary +, ++, --, and the ?: construct (for example, "x ? y : z"), as well as the , (comma) operator. Arithmetic bases are supported up to base 64. Floating point arithmetic is also supported. "typeset -E" (exponential) can be used to specify the number of significant digits and "typeset -F" (float) can be used to specify the number of decimal places for an arithmetic variable. The SECONDS variable now displays to the nearest hundredth of a second, rather than to the nearest second.
Compound variables Compound variables are supported. A compound variable allows a user to specify multiple values within a single variable name. The values are each assigned with a subscript variable, separated from the parent variable with a period (.). For example:
$ myvar=( x=1 y=2 ) 
$ print "${myvar.x}" 
1
Compound assignments Compound assignments are supported when initializing arrays, both for indexed arrays and associative arrays. The assignment values are placed in parentheses, as shown in the following example:
$ numbers=( zero one two three ) 
$ print ${numbers[0]} ${numbers[3]} 
zero three   
Associative arrays An associative array is an array with a string as an index.
The typeset command used with the -A flag allows you to specify associative arrays within ksh93. For example:
$ typeset -A teammates 
$ teammates=( [john]=smith [mary]=jones ) 
$ print ${teammates[mary]} 
jones
Variable name references The typeset command used with the -n flag allows you to assign one variable name as a reference to another. In this way, modifying the value of a variable will in turn modify the value of the variable that is referenced. For example:
$ greeting="hello"
$ typeset -n welcome=greeting     # establishes the reference 	
$ welcome="hi there"              # overrides previous value 	
$ print $greeting 	
hi there   
Parameter expansions The following parameter-expansion constructs are available:
  • ${!varname} is the name of the variable itself.
  • ${!varname[@]} names the indexes for the varname array.
  • ${param:offset} is a substring of param, starting at offset.
  • ${param:offset:num} is a substring of param, starting at offset, for num number of characters.
  • ${@:offset} indicates all positional parameters starting at offset.
  • ${@:offset:num} indicates num positional parameters starting at offset.
  • ${param/pattern/repl} evaluates to param, with the first occurrence of pattern replaced by repl.
  • ${param//pattern/repl} evaluates to param, with every occurrence of pattern replaced by repl.
  • ${param/#pattern/repl} if param begins with pattern, then param is replaced by repl.
  • ${param/%pattern/repl} if param ends with pattern, then param is replaced by repl.
Discipline functions A discipline function is a function that is associated with a specific variable. This allows you to define and call a function every time that variable is referenced, set, or unset. These functions take the form of varname.function, where varname is the name of the variable and function is the discipline function. The predefined discipline functions are get, set, and unset.
  • The varname.get function is invoked every time varname is referenced. If the special variable .sh.value is set within this function, then the value of varname is changed to this value. A simple example is the time of day:
    $ function time.get 
    > { 
    >     .sh.value=$(date +%r) 
    > } 
    $ print $time 
    09:15:58 AM 
    $ print $time    # it will change in a few seconds 
    09:16:04 AM
  • The varname.set function is invoked every time varname is set. The .sh.value variable is given the value that was assigned. The value assigned to varname is the value of .sh.value when the function completes. For example:
    $ function adder.set 
    > { 
    >   let .sh.value="
    $ {.sh.value} + 1" 
    > } 
    $ adder=0 
    $ echo $adder 
    1 
    $ adder=$adder 
    $ echo $adder 
    2  
  • The varname.unset function is executed every time varname is unset. The variable is not actually unset unless it is unset within the function itself; otherwise it retains its value.

Within all discipline functions, the special variable .sh.name is set to the name of the variable, while .sh.subscript is set to the value of the variables subscript, if applicable.

Function environments Functions declared with the function myfunc format are run in a separate function environment and support local variables. Functions declared as myfunc() run with the same environment as the parent shell.
Variables Variables beginning with .sh. are reserved by the shell and have special meaning. See the description of Discipline Functions in this table for an explanation of .sh.name, .sh.value, and .sh.subscript. Also available is .sh.version, which represents the version of the shell.
Command return values Return values of commands are as follows:
  • If the command to be executed is not found, the return value is set to 127.
  • If the command to be executed is found, but not executable, the return value is 126.
  • If the command is executed, but is terminated by a signal, the return value is 256 plus the signal number.
PATH search rules Special built-in commands are searched for first, followed by all functions (including those in FPATH directories), followed by other built-ins.
Shell history The hist command allows you to display and edit the shells command history. In the ksh shell, the fc command was used. The fc command is an alias to hist. Variables are HISTCMD, which increments once for each command executed in the shells current history, and HISTEDIT, which specifies which editor to use when using the hist command.
Built-in commands The enhanced Korn shell contains the following built-in commands:
  • The builtin command lists all available built-in commands.
  • The printf command works in a similar manner as the printf() C library routine. See the printf command.
  • The disown blocks the shell from sending a SIGHUP to the specified command.
  • The getconf command works in the same way as the stand-alone command /usr/bin/getconf. See the getconf command.
  • The read built-in command has the following flags:
    • read -d {char} allows you to specify a character delimiter instead of the default newline.
    • read -t {seconds} allows you to specify a time limit, in seconds, after which the read command will time out. If read times out, it will return FALSE.
  • The exec built-in command has the following flags:
    • exec -a {name} {cmd} specifies that argument 0 of cmd be replaced with name.
    • exec -c {cmd} tells exec to clear the environment before executing cmd.
  • The kill built-in command has the following flags:
    • kill -n {signum} is used for specifying a signal number to send to a process, while kill -s {signame} is used to specify a signal name.
    • kill -l, with no arguments, lists all signal names but not their numbers.
  • The whence built-in command has the following flags:
    • The -a flag displays all matches, not only the first one found.
    • The -f flag tells whence not to search for any functions.
  • An escape character sequence is used for use by the print and echo commands. The Esc (Escape) key can be represented by the sequence \E.
  • All regular built-in commands recognize the -? flag, which shows the syntax for the specified command.
  • The getopts built-in requires optstring to contain a leading + to allow options beginning with a + symbol.
Audit support

To enable the auditing feature in the enhanced Korn shell, complete the following steps:

  • To enable the auditing feature in the ksh93u command, the /etc/ksh_audit file must have an output filename an identification value for the user. For example, /tmp/ksh_auditfile;205;0.
  • You can configure the auditing feature to generate a detailed record for every executable command. You can use the record to monitor, track, and audit activities for one or more users on a system, including the system administrators.
  • To enable the auditing feature in the ksh93 command, the file /etc/ksh_audit must be created and configured by specifying the location of the audit_log file and an identification value for the user. You can separate the identification values by using a semicolon.

For example, the text /tmp/ksh_auditfile;0;100;205 in the /etc/ksh_audit file refers to the location of the log file (/tmp/ksh_auditfile), and the user identification values which are, 0 (root), 100, and 205 respectively.

Note:
  • The users awaiting audit must have Read and Write permissions for the configuration and log files.
  • When the EXTENDED_HISTORY environment variable is switched on, the audit entries will have a timestamp information with non-printable characters at the end of the entry. By default, the EXTENDED_HISTORY environment variable is turned on. However, you can manually turn it on by running the export EXTENDED_HISTORY=ON command. To disable the EXTENDED_HISTORY environment variable, you can run the unset EXTENDED_HISTORY command.
  • The EXTENDED_HISTORY environment variable allows you to view a detailed tracking report for all commands that are executed in the shell.
Other miscellaneous differences between Korn shell ksh and Korn shell ksh93 Other differences are:
  • With Korn shell ksh93, you cannot export functions using the typeset -fx built-in command.
  • With Korn shell ksh93, you cannot export an alias using the alias -x built-in command.
  • With Korn shell ksh93, a dollar sign followed by a single quote ($') is interpreted as an ANSI C string. You must quote the dollar sign (\"$\"') to get the old (ksh) behavior.
  • Argument parsing logic for Korn shell ksh93 built-in commands has been changed. The undocumented combinations of argument parsing to Korn shell ksh built-in commands do not work in Korn shell ksh93. For example, typeset -4i works similar to typeset -i4 in Korn shell ksh, but does not work in Korn shell ksh93.
  • With Korn shell ksh93, command substitution and arithmetic expansion is performed on special environment variables PS1, PS3, and ENV while expanding. Therefore, you must escape the grave symbol (`) and the dollar sign and opening parenthesis symbols ($() using a backslash (\) to retain the old behavior. For example, Korn shell ksh literally assigns x=$'name\toperator' as $name\toperator; Korn shell ksh93 expands \t and assigns it as name<\t expanded>operator. To preserve the Korn shell ksh behavior, you must quote $. For example, x="$"'name\toperator'.
  • The ERRNO variable has been removed in Korn shell ksh93.
  • In Korn shell ksh93, file names are not expanded for non-interactive shells after the redirection symbol.
  • With Korn shell ksh93, you must use the -t option of the alias command to display tracked aliases. The tracked alias feature is now obsolete, so the displayed aliases might not be tracked.
  • With Korn shell ksh93, in emacs mode, Ctrl+T swaps the current and previous character. With ksh, Ctrl+T swaps the current and next character.
  • Korn shell ksh93 does not allow unbalanced parentheses within ${name operator value}. For example, ${name-(} needs an escape such as ${name-\(} to work in both versions.
  • With Korn shell ksh93, the kill -l command lists only the signal names, not their numerical values.