sh, resh, ksh, bash

POSIX-compliant (Korn/Bourne-Again) shell and command interpreter 

Command


SYNOPSIS

sh [±abCefGHhiKkLmNnPprtuvwXx] [±o option] [-d directory] [-R name, env_piece, cmds] [cmd_file [argument...]]

sh [±abCefGHhiKkLmNnPprtuvwXx] [±o option] [-d directory] [-R name, env_piece, cmds] -c cmdstring [cmd_name [argument...]]

sh -s [±abCefGHhiKkLmNnPprtuvwXx] [±o option] [-d directory] [-R name, env_piece, cmds] [argument...]

resh [±abCefGHhiKkLmNnPptuvwXx] [±o option] [-d directory] [-R name, env_piece, cmds] [cmd_file [argument...]]

resh [±abCefGHhiKkLmNnPptuvwXx] [±o option] [-d directory] [-R name, env_piece, cmds] -c cmdstring [cmd_name [argument...]]

resh -s [±abCefGHhiKkLmNnPptuvwXx] [±o option] [-d directory] [-R name, env_piece, cmds] [argument...]

ksh [±abCefGHhikLmNnPprtuvwXx] [±o option] [-d directory] [-R name, env_piece, cmds] [cmd_file [argument...]]

ksh [±abCefGHhikLmNnPprtuvwXx] [±o option] [-d directory] [-R name, env_piece, cmds] -c cmdstring [cmd_name [argument...]]

ksh -s [±abCefGHhikLmNnPprtuvwXx] [±o option] [-R name, env_piece, cmds] [-d directory] [argument...]

bash [bash_options] [±abCefGHhiKkLmNnPprtuvwXx] [±o option] [-R name, env_piece, cmds] [-d directory] [cmd_file [argument...]]

bash [bash_options] [±abCefGHhiKkLmNnPprtuvwXx] [±o option] [-d directory] [-R name, env_piece, cmds] -c cmdstring [cmd_name [argument...]]

bash [bash_options] -s [±abCefGHhiKkLmNnPprtuvwXx] [±o option] [-d directory] [-R name, env_piece, cmds] [argument...]


DESCRIPTION

The sh utility is a sophisticated shell (command interpreter) that offers, depending on the options chosen, compatibility with the Korn, Bourne-Again, and POSIX shells available on many UNIX systems. You can use it as a replacement for the standard Windows command interpreter (cmd.exe)

When invoked with the sh name, sh is primarily a POSIX.2 compatible shell with some selected Korn and Bourne-Again shell behavior.

resh is a restricted version of that shell and is equivalent to sh -r. For more information on the restricted shell, see the description of the -r option. Regardless of how it is launched, this reference page uses resh to refer to the restricted shell.

ksh is a version of the shell that uses, by default, standard Korn behavior when it may conflict with bash or MKS KornShell behavior. ksh is equivalent to running sh with the -K or -o korn options. Regardless of how it is launched, this reference page uses ksh to refer to the shell operating in KornShell mode.

Finally, bash is a version of the shell that uses, by default, Bourne-Again Shell behavior when it may conflict with MKS KornShell or standard Korn behavior. bash is equivalent to running sh with the -o bash. Regardless of how it is launched, this reference page uses bash to refer to the shell operating in Bourne-Again Shell mode.

This page contains the following subsections:

Subsections dealing with substitution and interpretation of input appear in the order in which the KornShell performs those substitutions and interpretations.

Options and Invocation

The shell can be run interactively or as a script processor. Since interactive use is most common, it is described first. Normally you invoke the shell by logging in. You can also invoke the shell by typing an explicit sh command (or bash, ksh, or resh).

On Windows systems, any interactive shell starts by retrieving the set options from the registry. If you invoke the shell with a name that begins with the - character, it is invoked as a login shell which executes any profile files you have set up. (You can also get a login shell if you invoke the shell with -L or --login.) You can use profile files to customize your session with sh. For example, your profile files can set options, create aliases, or define functions and variables.

A login shell begins by executing the file:

$ROOTDIR/etc/profile.ksh 	(/etc/profile on UNIX systems)

In bash mode, the shell searches for the following files in order and executes the first one it finds:

$HOME/.bash_profile
$HOME/.bash_login
$HOME/profile.ksh 		($HOME/.profile on UNIX systems)
$HOME/.profile

Otherwise, in non-bash mode, the shell executes:

$HOME/profile.ksh 		($HOME/.profile on UNIX systems)

Note:

When the shell is searching for a profile file the HOME directory and the HOME environment variable is not set, the shell instead searches the current directory for a file with the same name and executes it if found.

When you launch a non-login shell in bash mode, the files:

$ROOTDIR/etc/bash.bashrc
$HOME/.bashrc

are executed in the order listed, if present. If $HOME/.bashrc does not exist, the shell executes the file specified by the ENV environment variable, if set.

If an interactive shell finds the ENV environment variable set when it begins execution (after profile processing), it executes the file named by the expansion of the value of this variable (see Variables). However, if the shell is in privileged mode (set by -p or -o privileged), it instead executes the file:

$ROOTDIR/etc/suid_pro.ksh 	($ROOTDIR/etc/suid_profile on UNIX systems)

If you launch a non-interactive, non-privileged shell in bash mode, the file indicated by the BASH_ENV environment variable is executed instead of the one indicated by ENV.

When 'pedantic posix' mode is set (settable with -o posix or with the POSIXLY_CORRECT and POSIX_PEDANTIC environment variables), the shell does not execute any profile files. It just runs the file indicated by the ENV environment variable, or if in privileged mode, the file:

$ROOTDIR/etc/suid_pro.ksh 	($ROOTDIR/etc/suid_profile on UNIX systems)

Note:

For all profile files discussed above that have both a Window-style and a UNIX-style name, if the shell does not find a file with the Windows-style name, it searches for a file with the UNIX-style name.

If there is at least one argument on the shell's command line, the first argument is taken as the name of a shell script to execute (the exception to this is when -s is used). Any additional arguments are assigned to the positional parameters, which usually serve as arguments to the shell script. See Parameter Substitution for information about positional parameters, and set for information about changing these parameters.

When a login shell in bash mode exits, it executes the following two files in the order listed if they exist:

$HOME/.bash_logout
$ROOTDIR/bash.bash_logout

Options

-c cmdstring 

executes cmdstring as if it were an input line to the shell and then exits. This is used by programs (for example, editors) that call the shell for a single command. sh assigns arguments in cmdstring to the positional parameters. If you specify cmd_name, special parameter 0 is set to this string for use when executing the commands in cmdstring.

Note:

sh ignores any command line options that follow -c on the command line.

-d directory 

runs the shell in the specified directory.

-G 

always writes shell errors to standard error and turns off all GUI features for the running shell. If this option is specified, it overrides set -o guierror.

-H 

starts the shell in hidden mode. This option is useful when running graphical functions from shell scripts.

-i 

invokes an interactive shell, as opposed to running a script. With -i, the shell catches and ignores interrupts. Without -i, an interrupt terminates the shell. For shells which read from the terminal, -i is the default.

-K 

specifies Korn-compatible behavior in any case where that behavior differs from the default shell behavior.

-L 

makes the shell a login shell as described earlier under Options and Invocation.

-N 

does not change to the $HOME directory before running the profile scripts. The profile scripts are run in whatever directory the shell was started in.

-R name, env_piece, cmds 

loads a saved shell environment at start-up. The shell environment to be loaded must be one previously saved with the mks_env built-in.

-r 

invokes a restricted shell (as noted earlier, you can also invoke a restricted shell by using the name resh). In a restricted shell, the following are not allowed or are not performed:

  • changing directories the cd command

  • changing the values of the variables ENV, PATH, or SHELL

  • specifying command names containing a slash (/) character

  • specifying a file name containing a slash (/) character as an argument to either the . built-in command or the -p to the hash built-in

  • importing function definitions from the shell environment at startup

  • parsing the value of the SHELLOPTS environment variable from the shell environment at startup

  • redirecting output with >, >|, <>, >&, &>, or >>.

  • specifying the -p option to the command built-in command.

  • turning off the restricted mode with set +r or set +o restricted.

These restrictions do not apply during execution of profile files.

-s 

reads commands from standard input and assigns all arguments to the positional parameters. Normally, if there is at least one argument to the shell, the first such argument is the name of a file to execute.

-w 

when exiting, displays [Hit return to continue] on the console and waits for the user to do so before closing the console window.

If you specify cmd_file without either the -c or -s option, the shell takes it as the name of a file containing commands to be run. Special parameter 0 is set to this name.

In addition, you can use the -a, -b, -C, -e, -f, -h, -i, -k, -m, -n, -o, -P, -p, -r, -t, -u, -v, -X, and -x options. You can specify these options with either a - to turn them off or a + to turn them on. The set reference page describes these options.

bash Options

When you invoke the shell in bash mode with bash command or by specifying -o bash with sh, resh, or ksh, you can also specify any of following bash-specific options:

Note:

When you use -o bash on the command line to invoke the shell in bash mode, -o bash must come before any bash-specific options.

--help 

displays the shell's usage message and exits.

--login 

is equivalent to the -L option.

--init-file file 
--rcfile file 

executes the specified file instead of the standard bash personal initialization file ($HOME/.bashrc) if the shell is interactive.

--noediting 

turns off the emacs, gmacs, and vi editing modes. This is equivalent to +o emacs +o gmacs +o vi.

--noprofile 

does not execute any of the following startup files when the shell is invoked as a login shell:

$ROOTDIR/etc/profile.ksh
$HOME/.bash_profile
$HOME/.bash_login
$HOME/profile.ksh
$HOME/.profile
--norc 

does not execute the file $HOME/.bashrc (or the file specified by ENV) when the shell is invoked as an interactive shell.

--restricted 

is equivalent to the -r option.

--verbose 

is equivalent to the -v option.

--version 

displays version information and exits. This version information is displayed as "MKS Bash, version $BASH_VERSION ($MACHTYPE)".

Command Syntax

The shell implements a sophisticated programming language that gives you complete control over the execution and combination of individual commands. When the shell scans its input, it always treats the following characters specially:

;   &   (   )   <   >   |   `   \   \"   '
space   tab   newline

To use any of these characters inside an actual argument, you must quote the argument (so that the shell doesn't use the special meanings of the characters). See Quoting for more information.

A simple command is a list of arguments separated by blanks or tabs.

When a word begins with an unescaped hash mark (#), the remainder of the line is treated as a comment and the shell discards input up to but not including the next newline.

When a command starts with a defined alias, sh replaces the alias with its definition (see alias).

A reserved word command starts with a reserved word (for example, if, while, for). Reserved word commands provide flow of control operations for the shell. These are described later in this section.

A command may be any of the following:

command:
        simple command
        reserved word command
        (command)
        command | command
        command && command
        command || command
        command & command
        command & 
        command |& 
        command ; command
        command ; 
        command <newline>

The following table gives the order of precedence of the preceding operators. Highest priority operators are listed first and operators on the same line have equal priority.

()
|
&&     ||
&  |&   ;  <newline>

You can also combine commands into a structure known as a compound-command which is simply a series of individuals commands joined together by these operators. The following list shows the meaning of these operations.

(compound-command 

executes the commands in compound-command in a subshell. This means that the current shell invokes a second shell to execute the commands. In this way, compound-command executes in a completely separate execution environment; it can change working directories, change variables, open files, and so on, without affecting the first shell. The subshell's environment begins as a copy of the current environment, so the value of the ENV environment variable is not used when a subshell starts.

| 

creates a pipe between the two commands that the | operator connects. This means that the standard output of the first command becomes the standard input of the second command. A series of commands connected by pipes is called a pipeline. The exit status is that of the last command in the pipeline.

Normally, the right hand side of the pipe is executed in a subshell. If the TK_SH_RHS_OF_PIPE_IN_CURRENT_SHELL environment variable is set, the right hand side is executed in the current shell.

&& 

is the logical AND operator. The shell executes the second command -- if and only if -- the first command returns a true (zero) exit status.

|| 

This is the logical OR operator. The shell executes the second command -- if and only if -- the first command returns a false (non-zero) exit status.

& 

asynchronously executes the command that precedes it. This means that the shell just starts the command running and then immediately goes on to take new input, before the command finishes execution.

|& 

executes the command that precedes it as a co-process. The command runs asynchronously, as with the & operator, but command's standard input and standard output are connected to the shell by pipes. The shell sends input to command's standard input with the print -p command and reads from command's standard output with the read -p command. The command should not buffer its output. Because of this and other limitations, a program intended to be used as a co-process must be designed as such.

; 

is the sequential execution operator. The second command is executed only after the first command has been completed.

<newline> 

the unescaped newline is equivalent to the ; operator.

The shell contains a rich set of reserved word commands which control the flow of a shell script and let you create compound commands. In the following list, a command can also be a sequence of commands separated by newlines. Italic square brackets ([]) indicate optional portions of commands and are never part of the command syntax.

! command 

The exclamation point is the logical NOT command. When its operand is false (non-zero), this command returns true (zero). When its operand is true (zero), this command returns false (non-zero).

{ compound-command;} 

Enclosing a command in braces is similar to the (compound-command construct except that the shell executes the compound-command in the same environment rather than under a subshell. { and } are simply reserved words to the shell. To make it possible for the shell to recognize these symbols you must put a blank or newline after the { and a semicolon or newline before the }.

case word in 
[[(]pattern[|pattern]) ...compound-command ;;] ... 
[[(]pattern[|pattern]) ...compound-command ;;] ... 
esac 

The case statement is similar to the switch statement of the C programming language or the case statement of Pascal. If the given word matches any one of the patterns separated by or-bar (|) characters, sh executes the corresponding compound-command. The patterns follow the rules given in File Name Generation except that the period (.) and slash (/) are not treated specially. Patterns are matched in the order they are given, so more inclusive patterns should be mentioned later. Once a pattern matching word has been found, no further patterns are expanded. You must use the double semicolon (;;) to delimit compound-command and introduce the next pattern.

Note:

By default, pattern-matching (like file name generation) in case statements is case-insensitive. To make pattern-matching case-sensitive, set the environment variable TK_DUALCASE_IN_CASE_STATEMENTS to any value. When TK_DUALCASE_IN_CASE_STATEMENTS is not set, the DUALCASE environment variable determines whether or not pattern-matching is case-sensitive in the same way it does for file name generation.

for variable [in word ...] 
do compound-command 
done 

The for statement sets variable to each word argument in turn, and executes the set of commands once for each setting of variable. If you omit the in word part, sh sets variable to each positional parameter. You may divert the flow of control within the loop with the break or continue statements.

The exit status of a for command is the exit status of the last command in the loop to execute. If the loop contains no commands, the exit status is zero.

function funcname { 
compound-command 
} 
funcname() { 
compound-command 
} 

Either of these forms defines a function named funcname, the body of which consists of the sequence of commands. You invoke a function just like any other command; when you actually call the function, sh saves the current positional parameters. The function's command line arguments then replace these parameters until the function finishes. If the option flag -K is set, sh also saves the current ERR and EXIT traps and any flags manipulated with the set command; these are restored when the function finishes. The function terminates either by falling off the end of the code of the function body, or by reaching a return statement. If the function uses typeset to declare any variables in the function body, the variables are local to the function.

The exit status of a function definition is zero, if the function was declared successfully; otherwise, it is greater than zero. The exit status of an invoked function is the exit status of the last command executed by the function.

if compound-command 
then compound-command 
[elif compound-command 
then compound-command] ... 
[else compound-command] 
fi 

In the if statement, if the first (leftmost) compound-command succeeds (returns a zero exit status), sh executes the compound-command following then; otherwise, sh executes the compound-command (if any) following the elif (which is short for "else if"); if that succeeds, sh executes the compound-command following the next then. If none of these cases hold, sh executes the compound-command following the else (if any).

The exit status of an if command is the exit status of the then compound-command or else compound-command that was executed, or zero, if none was executed.

select variable [in word ...] 
do compound-command 
done 

The select statement can handle menu-like interactions with the user. Its syntax is like the for statement. Each word is printed on the standard error file, one per line, with an accompanying number. If you omit the "in word..." part, sh uses the positional parameters. sh then displays the value of the variable PS3 to prompt the user to enter a numerical reply. If the reply is an empty line, sh displays the menu again; otherwise, sh assigns the input line to the variable REPLY, sets variable to the word selected, then executes the compound-command. sh does this over and over until the loop is terminated by interrupt, end-of-file, or an explicit break statement in the compound-command.

until compound-command1 
do compound-command2 
done 

The until statement executes compound-command1 and tests its exit status for success (zero) or failure (non-zero). If command1 succeeds, the loop terminates; otherwise, sh executes compound-command2, then goes back to execute and test compound-command1 again. Including break or continue commands in compound-command2 can affect the operation of the loop.

The exit status of an until command is the exit status of the last compound-command2 executed, or zero if none was executed.

while compound-command1 
do compound-command2 
done 

The while statement works like the until statement; however, the loop terminates whenever compound-command1 is unsuccessful (non-zero exit status).

The exit status of a while command is the exit status of the last compound-command2 executed, or zero if none was executed.

Shell reserved words are recognized only when they are the unquoted first token of a command. This lets you pass these reserved words as arguments to commands executed from the shell. The full list of reserved words is:


!         {         }
case      do        done
elif      else      esac
fi        for       function
if        select    then
until     while

Command Execution

A simple command consists of three optional parts: arguments, variable assignments, and redirection, which may appear in any order. For example:

variable=value argument0 argument1 <filename

is a simple command with one variable assignment, two arguments, and a redirection.

The command is processed as follows:

  1. sh performs word expansion on command arguments (see Word Expansion). The first word of the expanded arguments is the command name. If there are no arguments, sh only performs variable assignments and temporary redirection.
  2. sh performs word expansion on variable assignments. If there is no command or the command is a special built-in command (see Built-in Commands), variable assignments affect the current environment; otherwise, variable assignments affect the execution environment of the command.
  3. sh does redirection, performing word expansion on any file names (see File Descriptors and Redirection).

sh next searches for the command name and executes the command. If the command name is a special built-in command, sh invokes it. Most errors in special built-ins cause a non-interactive shell to exit.

If the command name is a function, sh executes the function. You can disable the search for functions with the built-in command named command.

If the command name is a regular built-in command, sh invokes it.

If the command name is not a regular or special built-in command or a function, sh searches for an executable file containing a shell script or a program. The shell uses one of the following two methods to locate this file.

Extra rules apply when searching paths on Windows. If no match for the command name has been found, the shell looks for a file that has the given name plus an extension. The extension can come from one of three possible sources.

First, the shell searches for the file using the extension list in the SHPATHEXT environment variable.

If the file was not found using SHPATHEXT, the shell searches for the file using the extension list in the PATHEXT environment variable. If the file was not found using PATHEXT, the shell searches for the file name with the .ksh extension, no extension, and the .sh extension (in that order). If .ksh, no extension, or .sh is included in the PATHEXT value, it is not searched for again at this step.

Finally, if the file still has not been found, the shell searches for a file that has the given name plus any of the following extensions:

.com 

This is a memory image file, used mostly for older software.

.exe 

This is the standard Windows executable file format.

.ksh or .sh 

This is a KornShell shell script. Such scripts are executed in a subshell of the current shell.

.bat 

Any such file is passed to cmd.exe for execution.

.cmd 

On 8.1/2012R2/10/2016/2019/11/2022, any such file is passed to cmd.exe and executed as a standard batch file appropriate to the operating system.

If an extension other than these is specified in SHPATHEXT or PATHEXT and that extension is not associated with a command line in the registry, the shell executes file with that extension as if it contains a shell script.

If the command name has a dot in it, the shell searches under PATH directories for files that have the name exactly as given. If the extension of the command name is .com, .exe, .ksh, .sh, .bat, or .cmd, the file is executed as described earlier.

If the extension of the command name (either explicitly specified or found using PATHEXT) is a file extension which is associated in the registry with an application, that application is used to run the file.

For example, suppose that you associated the .pl extension with the perl command in the registry. When you type:

foo.pl

the file foo.pl is run as though you specified:

perl foo.pl

Additionally, if .pl is included in the list of extensions in PATHEXT, the command:

foo

is the same as the command:

perl foo.pl

If the path search fails, the command exit status is 127. If sh cannot execute the program and it is not a shell script, the exit status is 126.

Note:

When the TK_DO_NOT_RUN_WITH_REG_ASSOCIATIONS environment variable is set, sh does not check the file associations in the registry when determining how to run a file.

When the HASHBANG environment variable is set to a non-zero value and the first line of a KornShell script file is of the form:

#![command] [arguments]

command is executed with a command line consisting of arguments followed by the path name of the script file. If command has a UNIX-style path name (starts with a forward slash and has no file name extension) and cannot be found, then, for portability reasons, the shell attempts a path search on the basename of command. For example, suppose the file script has the first line:

#!/usr/bin/perl

Typing script on the MKS KornShell command line executes the script using the perl command.

Note:

When the TK_HASHBANG_DO_NOT_SEARCH_PATH environment variable is set to a non-zero value and command cannot be found, the shell does not attempt a path search on the basename of command.

Command names may be marked as tracked aliases. The first time you execute a command with a tracked alias, the shell does a normal PATH search. If the search is successful, the shell remembers the file it finds. The next time you execute a command with the same name, sh immediately executes the file found on the last PATH search; there is no new search. This speeds up the search for the appropriate file.

The set -h command tells the shell that all commands should be treated as tracked aliases. See alias and set for more information.

Word Expansion

sh performs word expansion for simple commands, some reserved word commands, redirection file names, some shell variables (ENV, MAILPATH, PS1, and PS4), and unquoted here documents. There are four steps to expansion: substitution, word splitting, path expansion, and quote removal.

Directory substitution, parameter substitution, command substitution, and arithmetic substitution are each described in the appropriate section of this reference page.

After substitution, each word which underwent parameter substitution is checked for the characters in the IFS variable (by default, space, tab, and newline). If the word contains these characters, it is split into multiple words. When IFS contains an empty string, this word splitting is not performed.

If a word contains an unquoted *, ?, or ] or an an unquoted ?, +, @, !, or * followed by an open parentheses ((), that word is subject to path name expansion (see File Name Generation). Path name expansion is disabled if the -f or -o noglob shell flag is set (see set).

Finally, sh removes any quote characters (\, ', and ") from the original word. In here documents (see the description of number<<[-]name in the section File Descriptors and Redirection) and shell variables that expand, single and double quotes have no special meaning and are not removed.

sh may or may not do all of these steps, depending on where word expansion is performed. Table 1, Word Expansion summarizes what steps are done. The Arguments entry refers to the word list of for and select commands as well as simple commands.

Directory Other Word Path
Substitution Substitution Splitting Expansion

Arguments yes yes yes yes
Assignments yes yes no no
Redirection yes yes no yes/no*
Here documents no yes no no
Case statement yes yes no no
Shell variables no yes no no

* yes for interactive shell, no otherwise

Table 1: Word Expansion

Directory Substitution

When a word begins with an unquoted tilde (~), sh tries to perform directory substitution on the word. sh obtains all characters from the tilde (~) to the first backslash \ (/ on UNIX) and uses this as a user name. sh looks for this name in the user database. If sh finds a matching name, it replaces ~name with the name of the user's home directory, as given in the matching user database entry.

For example, if you specify a file name as:

~jsmith/file

sh looks up jsmith's home directory and put that directory name in place of the ~jsmith construct.

If you just specify a ~ without an accompanying name, sh replaces the ~ with the current value of your HOME variable (see Variables). For example:

echo ~

displays the name of your home directory. Similarly, sh replaces the construct tilde plus (~+) with the value of the PWD variable (the name of the your current directory), and replaces tilde hyphen (~-) with the value of OLDPWD (the name of your previous current directory). In variable assignments, tilde expansion is also performed after colons (:).

Parameter Substitution

The shell uses three types of parameters: positional parameters, special parameters, and variables. A positional parameter is represented with either a single digit (except 0) or one or more digits in curly braces (for example, 7 and {15} are both valid representations of positional parameters). Positional parameters are assigned values from the command line when you invoke sh.

A special parameter is represented with one of the following characters:

*    @    #    ?    !    -    $     0

The values to which special parameters expand are listed later in this section.

Variables are named parameters. For details on naming and declaring variables, see Variables.

The simplest way to use a parameter in a command line is to enter a dollar sign ($) followed by the name of the parameter. For example, if you enter the command:

echo $x

sh replaces $x with the value of the parameter x and then displays the results (because echo displays its arguments). Other ways to expand parameters are shown later in this section.

Some parameters are built-in to the shell. These are as follows:

$1, $2, ... $9 

expands to the dth positional parameter (where d is the single digit following the $. If there is no such parameter, $d expands to a null string.

$0 

expands to the name of the shell, the shell script, or a value assigned when you invoked the shell.

$# 

expands to the number of positional parameters. The parameter assigned to $0 is not counted in this number, since it is a special parameter, not a positional parameter.

$@ 

expands to the complete list of positional parameters. If $@ is quoted, the result is separate arguments, each quoted. This means that:

"$@"

is equivalent to:

"$1" "$2" ...
$* 

expands to the complete list of positional parameters. If $* is quoted, the result is concatenated into a single argument, with parameters separated by the first character of the value of IFS (see Variables). For example, if the first character of IFS is a space:

"$*"

is equivalent to:

"$1 $2 ..."

If IFS is unset, the parameters are separated by a space.

Note that setting IFS to an empty string is not the same as unsetting it. In this case, the parameters are separated by the null string and as a result, concatenated.

$- 

expands to all options that are in effect from previous calls to the set command and from options on the sh command line.

$? 

expands to the exit status of the last command executed.

$$ 

expands to the process number of the original parent shell.

$! 

expands to the process number of the last asynchronous command.

These constructs are called parameters of the shell. They include the positional parameters, but are not restricted to the positional parameters.

We have already mentioned that you can expand a parameter by putting a $ in front of the parameter name. More sophisticated ways to expand parameters are:

${parameter} 

expands any parameter.

${number} 

expands to the positional parameter with the given number. (When using $d to refer to the dth positional parameter, d must be a single digit; with brace brackets, number can be greater than nine.) Since braces mark the beginning and end of the name, you can immediately follow the expression with a letter or digit.

${parameter[arithmetic expression]} 

expands to the value of an element in an array named by parameter. The arithmetic expression gives the subscript of the array. (See Arithmetic Substitution.)

${parameter[*]} 

when unquoted, expands to all elements in the array named by parameter. When quoted, it expands to all elements in the array separated by the first character in IFS.

${parameter[@]} 

when unquoted, is the same as ${parameter[*]}. When quoted as "${parameter[@]}", it expands to all the elements in the array named by parameter, each quoted individually.

${#parameter} 

expands to the number of characters in the value of the given parameter.

${#*}, ${#@} 

expands to the number of positional parameters.

${#parameter[*]} 

expands to the number of elements in the array named by parameter. Elements that do not have assigned values do not count. For example, if you only assign values to elements 0 and 4, the number of elements is 2. Elements 1 through 3 do not count.

${parameter:-word} 

expands to the value of parameter if it is defined and has a non-empty value; otherwise, it expands word. This means that you can use word as a default value if the parameter isn't defined.

${parameter-word} 

is similar to the preceding construct, except that the parameter is expanded, if defined, even if the value is empty.

${parameter:=word} 

expands word with parameter expansion and assigns the result to parameter, provided that parameter is not defined or has an empty value. The result is the expansion of parameter, whether or not word was expanded.

${parameter=word} 

is similar to the preceding construct, except that the parameter must be undefined (it can't just be null) for word to be expanded.

${parameter:?word} 

expands to the value of parameter provided it is defined and non-empty. If parameter isn't defined or is null, sh expands and displays word as a message. If word is empty, sh displays a default message. Once a non-interactive shell has displayed a message, it is terminated.

${parameter?word} 

is similar to the preceding construct, except that sh displays word only if parameter is undefined.

${parameter:+word} 

expands word, provided that parameter is defined and non-empty.

${parameter+word} 

expands word, provided that parameter is defined.

${parameter#pattern} 

attempts to match pattern against the value of the specified parameter. The pattern is the same as a case pattern. sh searches for the shortest prefix of the value of parameter that matches pattern. If sh finds no match, the previous construct expands to the value of parameter; otherwise, the portion of the value that matched pattern is deleted from the expansion.

${parameter##pattern} 

is similar to the preceding construct, except that sh deletes the longest prefix that matches pattern if it finds such a match.

${parameter%pattern} 

searches for the shortest suffix of the value of parameter matching pattern and deletes the matching string from the expansion.

${parameter%%pattern} 

is similar to the preceding construct, except that sh deletes the longest suffix that matches pattern if it finds such a match.

${parameter:offset:len} 
${parameter:offset} 

expands to a substring of parameter which has a length of len characters beginning at the character position indicated by offset (the first character is offset 0). If you omit :len or offset+len is greater than the length of parameter, the substring ends with the last character of parameter. Finally, if offset is greater than the length of parameter, this construct expands to a null string.

${parameter/pat/str} 

expands to a string which is the value of parameter with the first occurrence of the pattern pat replaced by the string str. If you omit /str or str, the matched characters are deleted.

${parameter//pat/str} 

expands to a string which is the value of parameter with each occurrence of the pattern pat replaced by the string str. If you omit /str or str, the matching characters are deleted.

${parameter/#pat/str} 

expands to a string which is the value of parameter where an occurrence pattern pat which matches the beginning characters of parameter's value is replaced by the string str. If you omit /str or str, the matching characters are deleted.

${parameter/%pat/str} 

expands to a string which is the value of parameter where an occurrence pattern pat which matches the final characters of parameter's value is replaced by the string str. If you omit /str or str, the matching characters are deleted.

Arithmetic Substitution

Arithmetic substitution is available with the syntax:

$((arithmetic expression))

or:

$[arithmetic expression]

sh replaces this sequence with the value of arithmetic expression. Arithmetic expressions consist of expanded variables, numeric constants, and operators.

Numeric constants have the form:

[base#]number

where the optional base is a decimal integer between 2 and 36 inclusive, and number is a non-negative number in the given base. The default base is 10. Undefined variables evaluate to zero.

Table 2, Shell Operators, lists the operators in decreasing order of precedence. Operators sharing a heading have the same precedence. Evaluation within a precedence group is from left to right, except for the assignment operator which evaluates from right to left.

Arithmetic expressions may be used without the enclosing $(( and ) in assignment to an integer variable (see typeset); as an argument to the following built-in commands:

break    continue    exit    let    return    shift

Summary of Operators

Unary Operators
var++ ++var postfix/prefix increment
var-- --var postfix/prefix decrement
- unary minus
! logical negation
+ ~ identity, bitwise negation

Multiplicative Operators
* / % multiplication, division, remainder

Additive Operators
+ - addition, subtraction

Bitwise Shift Operators
<< >> bitwise shift right, bitwise shift left

Relational Operators
< > less than, greater than
<= >= less than or equal, greater than or equal
== != equal to, not equal to

Bitwise And Operator
& and

Bitwise Exclusive Or Operator
^ exclusive or

Bitwise Inclusive Or Operator
| inclusive or

Logical And Operator
&& logical and

Logical Or Operator
|| logical or

Conditional Operator
? : if-else

Assignment Operator
= *= /= %= assignment
+= -= <<=
>>= &= ^= |=

Table 2: Shell Operators

Command Substitution

In command substitution, sh uses the expansion of the standard output of one command in the command line for a second command. There are two syntaxes.

The first syntax (called backquoting) surrounds a command with grave accents (`), as in:

ls -l `cat list`

To process this command line, sh first executes the cat command and collects its standard output. The shell then breaks this output into arguments and puts the result into the command line of the ls command. The previous command therefore lists the attributes of all files, the names of which are contained in the file list.

This syntax is easy to type, but is not useful if you want to put one command substitution inside another (nesting command substitutions). A more useful syntax is:

$(command)

as in:

vi $(fgrep -l function $(find . -name '*.c'))

This command uses find to search the current directory and its subdirectories to find all files, the names of which end in .c. It then uses fgrep to search each such file for those that contain the string function. Finally, it calls Vi to edit each such file.

There is an historical inconsistency in the backquoting syntax. A backslash (\) within a backquoted command is interpreted differently depending on its context. Backslashes are interpreted literally unless they precede a dollar sign ($), grave accent (`), or another backslash (\); in these cases, the leading backslash becomes an escape character to force the literal interpretation of the $, `, or \. Consequently, the command:

echo '\$x'

issued at system level produces the output:

\$x

while the same command nested in a backquoted syntax:

echo `echo '\$x'`

produces the output:

$x

For improved readability, the $(command syntax is recommended for command substitutions.

sh performs command substitutions as if a new copy of the shell had been invoked to execute the command. This affects the behavior of $- (standing for the list of options passed to the shell). If a command substitution contains $-, the expansion of $- does not include the -i option, since the command is being executed by a non-interactive shell.

Quoting

To let you override the special meaning of certain words or special characters, the shell provides several quoting mechanisms. In general, you can turn off the special meaning of any character by putting a backslash (\) in front of the character. This is called escaping the character.

You can also use this method to tell the shell to disregard the special meaning of the newline character by putting a backslash at the end of a line. The shell ignores the escaped newline and joins the next line of input to the end of the current line. In this way, you can enter long lines in a convenient and readable fashion.

Escaping characters by putting a backslash in front of them is the most direct way of telling the shell to disregard special meanings; however, it can be awkward and confusing if you have several characters to escape.

As an alternative, you can put arguments in various types of quotes. Different quote characters have different strengths. The apostrophe (single quote) characters are the strongest. When you enclose a command line argument in apostrophes, the shell disregards the special meanings of everything they contain. For example:

echo '*'

displays the * character, rather than interpreting the * as a special character.

Double quote characters are weaker. Inside double quotes, the shell performs command substitutions of the form:

$(command)
   or
`command`

(See Command Substitution.) The shell does not perform such substitutions when they appear inside apostrophes. In addition, the shell performs parameter substitutions of the form:

$parameter

when they are inside double quotes but not when they're inside apostrophes (see Parameter Substitution). As well, you can use the backslash to escape another character inside double quotes, but inside apostrophes, the shell ignores this special meaning.

The shell treats internal field separator characters (that is, characters in the value of the IFS variable) literally inside quoted arguments, whether they're quoted with double quotes or apostrophes. This means that a quoted argument is considered a single entity, even if it contains IFS characters.

Quoting can override the special meanings of reserved words and aliases. For example, in:

"select" program

the quotes around select tell the shell not to interpret select as a shell reserved word. Instead, sh does a normal command search for a command named select.

You must always quote the following characters if you want sh to interpret them literally:

|   &   ;   <   >   (   )   $    '   "   `   \
<space>  <tab>  <newline>

The following characters need to be quoted in certain contexts if they are to be interpreted literally.

*   ?   [   #   %   =   ~

Finally, you can quote strings with the $'string' construct. This construct is similar to quoting the string with single quotes except the following backslash-escaped characters are replaced as specified by the ANSI C standard:

Escape Character

\a alert (bell)
\b backspace
\e an escape character (not ANSI C)
\E same as \e
\f formfeed
\n newline
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\' single quote
\ooo character with octal value ooo
\xdd character with hexadecimal value dd
\cX a control-X character

File Descriptors and Redirection

The shell sometimes refers to files using file descriptors. A file descriptor is a number in the range 0 through 9. It may have any number of digits. For example, the file descriptors 001 and 01 are identical to file descriptor 1. Various operations can associate a file descriptor with a particular file; the exec command is used to manipulate file descriptors directly.

Some file descriptors are set up at the time the shell starts up. These are the standard input/output streams:

Commands running under the shell can use these descriptors and streams too. When a command runs under the shell, the streams are normally associated with your terminal; however, you can redirect these file descriptors to associate them with other files (so that I/O on the stream takes place on the associated file instead of your terminal). In fact, the shell lets you redirect the I/O streams associated with file descriptors 0 through 9, using the following command line constructs.

number<file 

uses file for input on the file descriptor number. If you omit number, as in <file, the default is 0; this redirects the standard input.

number>file 

uses file for output on the file descriptor number. If you omit number, as in >file, the default is 1; this redirects the standard output. The shell creates the file if it doesn't already exist. The redirection fails if the file already exists and noclobber is set (see set).

number>|file 

is similar to number>file but if file already exists, it overwrites the current contents of the file.

number<>file 

uses file for input and output with the file descriptor number. This is most useful when the file is another terminal or modem line. If you omit number, as in <>file, the default number is zero; this redirects the standard input. Output written to the file overwrites the current contents of the file (if any). The shell creates the file if it doesn't already exist.

number>>file 

is similar to number > file except that output is appended to the current contents of file (if any).

number<<[-]name 

lets you specify input to a command from your terminal (or from the body of a shell script). This notation is known as a here document. The shell reads from the standard input and feeds that as input to file descriptor number until it finds a line that exactly matches the given name. If you omit number, the default is the standard input. For example, to process the command:

cat <<abc >out

the shell reads input from the terminal until you enter a line that consists of the word abc. This input is passed as the standard input to the cat command, which then copies the text to the file out.

If any character of name is quoted or escaped, sh does not perform substitutions on the input; otherwise, it performs variable and command substitutions, respecting the usual quoting and escape conventions. If you put - before name, sh deletes all leading tabs in the here document.

number<&word 

makes the input file descriptor number a duplicate of the file descriptor identified by the expansion of word. If you omit number, the default is the standard input (file descriptor 0). After expansion, the word can be a digit representing a file descriptor (0-9), or a minus sign (-). For example, <&4 makes the standard input a duplicate of file descriptor 4. In this case, entering input on 4 has the same effect as entering input on the standard input.

If word expands to -, the shell closes the file descriptor named by number.

number1>&word 

makes the output file descriptor number a duplicate of the file descriptor identified by the expansion of word. If you omit number, the default is the standard output (file descriptor 1). After expansion, the word can be a digit representing a file descriptor (0-9), or a minus sign (-). For example, >&2 makes the standard output a duplicate of file descriptor 2 (the standard error). In this case, writing output on the standard output has the same effect as writing output on the standard error.

If word expands to -, the shell closes the file descriptor named by number.

number<&- 

closes input descriptor number. If you omit number, it closes the standard input.

number>&- 

closes output descriptor number. If you omit number, it closes the standard output.

Normally, redirection only applies to the command where the redirection construct appears (see exec).

The order of redirection specifications is significant, since an earlier redirection can affect a later one; however, these specifications may be freely intermixed with other command arguments. Since the shell takes care of the redirection, these constructs are not passed to the command itself.

Note:

The shell performs the implicit redirections needed for pipelines before performing any explicit redirections.

File Name Generation

The characters *, ? and [ are called glob characters or wild card characters. If an unquoted argument contains one or more glob characters, the shell processes the argument for file name generation. The glob characters are part of glob patterns which represent file and directory names. These patterns are similar to regular expressions, but differ in syntax, since they are intended to match file names and words (not arbitrary strings). The special constructions that may appear in glob patterns are:

? 

Matches exactly one character of a file name, except for the separator character / and a . at the beginning of a file name. On Windows systems, it does not match the separator character \ either. ? only matches an actual file name character and does not match nonexistent characters at the end of the file name. ? is analogous to the metacharacter . in regular expressions.

* 

Matches zero or more characters in a file name, subject to the same restrictions as ?. * is analogous to the regular expression .*. Unlike the standard Windows wild card syntax, *x.c is a valid pattern.

[chars] 

Defines a class of characters; the glob pattern matches any single character in the class. A class may contain a range of characters by writing the first character in the range, a dash - and the last character. For example, in the POSIX locale [A-Za-z] stands for all the uppercase and lowercase letters. If you want a literal - character in the class, put it as the first or last character inside the brackets. If the first character inside the brackets is an exclamation mark (!), the pattern matches any single character that is not in the class.

Glob patterns can also contain pattern lists. A pattern list is a sequence of one or more patterns separated by either | or &. If two patterns are separated by |, only one of the two patterns must match. If two patterns are separated by &, both patterns must match.

A sub-pattern begins with a ?, *, +, @, or ! character followed by a pattern-list enclosed in parentheses. Pattern-lists themselves can contain sub-patterns. The following list describes valid sub-patterns.

?(pattern-list) 

Matches exactly zero or exactly one occurrence of the specified pattern-list.

*(pattern-list) 

Matches zero or more occurrences of the specified pattern-list.

+(pattern-list) 

Matches one or more occurrences of the specified pattern-list.

@(pattern-list) 

Matches exactly one occurrence of the specified pattern-list.

!(pattern-list) 

Matches any string that does not match the specified pattern-list.

Some sample patterns are:

[!a-f]*.c 

matches all .c files beginning with something other than the letters a through f.

/???/?.? 

matches all files under the root directory in a directory that has a three letter name. The files must have a base name containing one character followed by a . and another single character.

*/*.[chyl] 

matches all .c, .h, .y, and .l files in a subdirectory of the current directory.

~mks/*.ksh 

matches all shell scripts in the home directory of user mks (see Directory Substitution for the use of ~).

test_?([fr]un|log)_file 

matches files with the names test__file, test_fun_file, test_run_file, and test_log_file.

prog*([a-z]).c 

matches the file prog.c and any .c file whose name consists of prog followed by any combination of lowercase letters.

file+([0-9]) 

matches all files whose names consist of the word file followed by one or more digits.

@(install|setup|config).bat 

matches the file names install.bat, setup.bat, and config.bat.

*.!([bcd]at) 

matches all files except those with .bat, .cat, or .dat extensions.

If no files match the pattern, sh leaves the argument untouched. If the set option -f or -o noglob is in effect, the shell does not perform file name generation.

Note:

By default, file name generation is case-insensitive. If you want file name generation to be case-sensitive, set the environment variable DUALCASE to any value. Setting DUALCASE also makes pattern-matching in case structures case-sensitive.

Variables

The shell maintains variables and can expand them when they are used in command lines; see Parameter Substitution for details.

A variable name must begin with an uppercase or lowercase letter or the underscore (_). Subsequent characters in the name, if any, may be uppercase or lowercase letters, underscores, square brackets (which must be escaped with a backslash (\)), and/or digits 0 through 9.

You can assign a value to a variable with:

variable=value

You may implicitly declare a variable as an array by using a subscript expression when assigning a value, as in:

variable[arithmetic expression]=value

You can use a subscripted array variable anywhere that the shell allows an ordinary variable. See the section on Arithmetic Substitution for the syntax of an arithmetic expression. Also see typeset, export, and readonly for details about the attributes of shell variables and how shell variables may be exported to child processes.

For a list of variables that the shell either sets or understands, see ENVIRONMENT VARIABLES.

Shell Execution Environments

A shell execution environment is the set of conditions affecting most commands executed within the shell. It consists of:

A subshell environment starts as a duplicate of the shell environment, except that traps caught by the shell are set to default values in the subshell. Since the subshell environment starts as a duplicate, the value of the ENV environment variable is not run. Changes made to a subshell environment do not affect the shell environment.

Command substitutions, commands within parentheses (for example, (command), and commands to be run asynchronously (for example, command&) all run in subshell environments. Each command in a pipeline command|command runs in a subshell environment.

Shell utilities also run in a separate environment which does not affect the shell environment, except for certain built-in utilities (for example, cd and umask) which explicitly alter the shell environment. The shell sets up a shell utility's environment to include the following:

Built-in Commands

Some commands are built into the shell. Building such commands into the shell increases the performance of shell scripts and allows access to the shell's internal data structure and variables. For details on a command, see its reference page. These internal commands have semantics indistinguishable from external commands.

The exact list of built-in commands differs on various systems. Use the whence command to determine if a specific command is a built-in on your system. The most common built-in commands are listed here:

:		.		[[
[ 		alias 		basename
break 		cd		chmod
command 	continue	date
declare		dirname		dlg
echo		eval		exec
exit		export		false
fc		getopts		jobs
kill		let		local
mkdir		mks_env		print
pwd		read		readonly
return		rm		rmdir
set		shift		shopt
source		test		time
touch		trap		true
type		typeset		umask
unalias		uname		unset
wait		whence

POSIX.2 recognizes a subset of these commands as special built-ins. Syntax errors in special built-in commands cause a non-interactive shell to exit with the exit status set by the command. The special built-in utilities are:

: 		. 		break
continue 	eval 		exec
exit 		export 		readonly
return 		set 		shift
trap 		typeset 	unset

On Windows systems, the umask command does nothing; in the interest of compatibility with POSIX and UNIX systems, the shell still recognizes the command but it has no effect.

As well as built-in commands, the shell has a set of predefined aliases:

autoload	functions	hash
hist		history		integer
r		stop		suspend

See alias for details.

Command Line Editing

Windows systems use a number of keys, such as BACKSPACE and ESC for special input editing functions. By default, the KornShell leaves command line editing to the operating system using these familiar functions. However, these functions are not particularly powerful or friendly. As an alternative, the shell has built-in facilities for interactive command editing and file name generation that not only aid in composing new commands but also provide for convenient modification and re-execution of previous commands. This capability is distinct from that provided by the fc command, which passes previous command lines to a separate program for editing. The built-in facilities mimic the emacs, gmacs, or Vi screen editors, and are enabled by the following commands: (see set and vi for details.)

set -o emacs
set -o gmacs
set -o vi

These facilities are also enabled (with the corresponding option set) by assigning a value ending in emacs, gmacs, or vi to the variable EDITOR or VISUAL.

When the shell is in bash mode, it defaults to emacs editing mode. In other modes, it defaults to no command line editing.

Unlike full-screen editors, shell editing uses a one-line window, extending from the end of the prompt to the second-last column. Multi-line history entries are displayed with newlines represented as ^J. The number of columns on the output device is obtained from the COLUMNS variable if defined; otherwise, it is assumed to be 80. A command line that extends into the rightmost column can be scrolled horizontally. If you try to move the cursor beyond the edge of the window, the line is scrolled to approximately centre the cursor in the window. The second last column displays a character marking a scrollable line: < indicates extra data off the left; > indicates extra data off the right; and * indicates extra data off both sides.

EMACS/GMACS Editing Mode

When this editing mode has been enabled, by any of the means noted earlier, ordinary printable characters from the keyboard are entered in the command line (and echoed). Various control characters introduce command sequences for such things as moving the cursor, scrolling through the command history, and modifying the current command. The only difference between emacs and gmacs mode is in the handling of CTRL-T (see the description of CTRL-T in the Text Change subsection).

The command sequences recognized are listed in functional groups. The notation META-c represents ESC followed by the letter c. The terminology is historical. Many commands accept an optional preceding count n, which is entered in decimal as META-digits, or as CTRL-U which multiplies the current count (initially 1) by 4. The command is executed that number of times.

n CTRL-B 
n 

Move the cursor back n characters.

n CTRL-F 
n 

Move the cursor forward n characters.

CTRL-A 

Move the cursor to beginning of line.

CTRL-E 

Move the cursor to end of line.

nMETA-b 

Move the cursor back to nth previous beginning of word (string of alphanumerics).

nMETA-f 

Move the cursor forward to nth beginning of word.

CTRL-]c 

Move the cursor forward to next character c on current line.

META-space 
CTRL-@ 

Set mark at cursor position.

CTRL-X CTRL-X 

Exchange cursor position and mark.

These commands display a different history line.

n CTRL-P 
n 

Select the nth previous command line from history.

n CTRL-N 
n 

Select the nth next command line from history.

META-< 

Select the earliest command line from history.

META-> 

Select the latest command line from history.

n CTRL-R>stringENTER 

Select the nth previous command line matching string. If n is zero, then select the next matching command after the current line.

n erase (erase character) 
nBACKSPACE 
n CTRL-H 

Delete n characters to the left of the cursor.

n CTRL-D 

Delete n characters to the right of the cursor. If the current line is empty, then terminate the shell.

nMETA- CTRL-H 
nMETA-h 

Delete to the nth beginning of word before the cursor.

nMETA-d 

Delete to the nth beginning of word after the cursor.

n CTRL-K 

Delete from the cursor to the end of line. If n is zero, then delete from the beginning of line to the cursor.

kill (line kill character) 
CTRL-G 

Delete entire current line.

CTRL-W 

Delete from cursor position to the mark (set with META-space or CTRL-@).

CTRL-T 

In emacs mode, transpose the current character with the previous character and move the cursor forward. If the cursor is at the end of the line, or in gmacs mode, transpose the previous two characters.

CTRL-Y 

Restore the last text deleted in emacs mode.

CTRL-^ 

Capitalize character under cursor.

META-c 

Capitalize word to right of cursor.

META-l 

Lowercase word to right of cursor.

META-u 

Uppercase word to right of cursor.

nMETA-. 
nMETA-_ 

Insert the nth word of the previous command. If n is not given or it is zero, insert the last word of the previous command.

META-* 

Replace the current word with the list of files which would match that word with a * appended.

META-ESC 

Used to complete the name of a path, shell built-in, function, or variable. If there is only one existing name that matches as much as you've typed, the name is completed and a space is be added after the complete name. If there are several matching names, the shell expands what you've typed by adding all the characters that are common to all matching names.

If the shell option tabcomplete is set (see set), hitting the <tab> key accomplishes the same thing.

META-= 

Lists all path, shell built-in, function, or variable names matching the current word.

If the shell option tabcomplete is set (see set), hitting the <tab> key twice accomplishes the same thing.

CTRL-C 

Abort current command line.

CTRL-J 
CTRL-M 
ENTER 

Execute current command line.

CTRL-L 

Re-display current command line.

CTRL-O 

Remember the next command line, execute the current command line, then select the remembered line.

CTRL-U 

Multiply the count on the following command by 4 (for each CTRL-U).

CTRL-V 

Display the version of the shell.

\ 

Take the next character literally. Thus command and control characters can be entered in a command line or search string.

eof (end-of-file character) 
CTRL-Z (on Windows systems) 
CTRL-D 

Terminate the shell.

META-n 

Enter a count for the following command.

Vi Editing Mode

When the Vi editing facilities have been enabled by any of the means discussed in the first paragraph, the shell is initially in input mode after each new prompt. Keyboard input is normally inserted at the current position in the current command line; the exceptions are the following action keys.

Note:

In input mode, the cursor arrow keys are ignored.

erase (erase character) 
BACKSPACE 
CTRL-H 

Delete the character to the left of the cursor.

eof (end-of-file character) 
CTRL-Z (on Windows systems) 
CTRL-D 

Terminate the shell.

CTRL-W 

Delete the word (white-space delimited string) to the left of the cursor.

kill (line kill character) 
CTRL-U (on Windows systems) 
CTRL-X 

Delete the current line.

CTRL-J 
CTRL-M 
ENTER 

Execute the current line.

ESC 

Switch from input mode to command mode (see below).

CTRL-V 

Take the next character literally; useful for entering any of these action keys as text.

\ 

Escape the following action key. If the next character is any action key except CTRL-J, CTRL-M, or ENTER, the \ is erased and the escaped character is entered literally; otherwise the \ is entered, and the next character is treated normally.

If the ESC key is pressed, the shell enters command mode, and keyboard input is interpreted as commands to reposition the cursor, scroll through the command history, delete or change text, or re-enter input mode. In command mode input is not echoed; it is acted upon. Many commands take an optional count, n, which is entered as a preceding decimal number (not echoed); the command is executed that number of times. Except where otherwise noted, n defaults to 1. Commands are discussed in functional groups.

These commands reposition the cursor in the command line.

nh 
n 

Move back n characters.

nl 

Move forward n characters.

0 

(zero) -- Move to the first character on the line.

^ 

Move to the first non-blank character on the line.

$ 

Move to the last character on the line.

nw 

Move to the beginning of the nth next word (string of alphanumerics, or of non-blank non-alphanumerics).

nW 

Move to the beginning of the nth next full-word (string of non-blanks).

nb 

Move to the nth previous beginning of word.

nB 

Move to the nth previous beginning of full-word.

ne 

Move to the nth next end of word.

nE 

Move to the nth next end of full-word.

nfc 

Move to the nth next character c.

nFc 

Move to the nth previous character c.

ntc 

Move to the character before the nth next character c.

nTc 

Move to the character after the nth previous character c.

n; 

Repeat the previous f, F, t, or T command.

n, 

Repeat the previous f, F, t, or T command, but in the opposite direction.

% 

Move to the balancing character if the cursor is positioned on one of the following characters:

(   )   {   }   [   ]   <   >

If the cursor is not positioned on one of these characters, the rest of the line is searched for the first occurrence of one of these characters and the cursor is then moved to its balancing character.

The following change the current (displayed) command line.

nj 
n+ 
n 

Select the nth next command line from history.

nk 
n- 
n 

Select the nth previous command line from history.

nG 

Select the command with history number n, or the latest command if n is omitted.

n/stringENTER 

Select the nth command line, searching backwards, which matches string. If string is omitted, the previous search string is used.

n?stringENTER 

Select the nth command line, searching forwards, which matches string. If string is omitted, the previous search string is used.

nn 

Repeat the last string search (`/' or `?') command.

nN 

Repeat the last string search, but in the opposite direction.

The following commands alter the text in the current command line. Some of these commands operate on a text block, defined by an immediately following cursor movement command. This is designated by m (for movement) in the text change command. The text block extends from the current cursor position to the new position determined by the movement command.

i 

Enter input mode, inserting text before the character under the cursor.

I 

Insert before first non-blank on line (^i).

a 

Move the cursor forward one character and enter input mode, appending text after the character originally under the cursor.

A 

Append to end of line ($a).

ndm 

Delete text block. If n is given, it is applied to the movement.

dd 

Delete entire command line.

D 

Delete from cursor to end of line (d$).

nx 

Delete n characters to right of cursor (ndl).

nX 

Delete n characters to left of cursor (ndh).

ncm 

Change text block; deletes block of text and enters input mode. If n is given, it is applied to the movement.

cc 
S 

Change entire command line.

ns 

Change next n characters from cursor.

np 

Put back, after the character under the cursor, n copies of the last block deleted by a text change command.

nP 

Put back, before the character under the cursor, n copies of the last block deleted by a text change command.

rc 

Replace the single character under the cursor with the character c, and advance the cursor one position.

R 

Enter replace mode: a special case of input mode in which each character entered overwrites that under the cursor, and advances the cursor one position.

u 

Undo the last text change to the current line. This is itself a text change command, and so acts as a toggle for the last change.

U 

Undo all changes to the current line.

n~ 

Invert the case of the next n characters, advancing the cursor over them.

n. 

Repeat the last text change command. If n is given, it overrides the count originally given with the repeated command.

n_ 

Append after the character under the cursor, the nth argument from the previous command line (default last), and enter input mode.

* 

Replace the current word with the list of file names that would match the word with a * appended. In the case of no match, the terminal beeps and the word is not changed; otherwise, the cursor is positioned at the end of the list and input mode is entered.

\ 

Complete a path, shell built-in, function, or variable name. If there is only one existing name that matches as much as you've typed, the name is completed and a space is added after the complete name. If there are several matching names, the shell expands what you've typed by adding all the characters that are common to all matching names.

If the shell option esccomplete is set (see set), hitting the ESC key twice accomplishes the same thing.

= 

Lists all path, shell built-in, function, and variable names matching the current word.

If the list is larger than one screenful, the first screenful of matching names is displayed and you are prompted with the message:

Display all n possibilities? (y or n).

where n is the number of matching path names. If you answer y, an internal pager is used to page through the the matches.

The internal pager commands are:

y, Y, <space>		     show next screenful of potential matches
<return>, <newline> 	     show next potential match
n, N, q, Q, Ctrl-G, <DEL>    stop showing matches

If the shell option tabcomplete is set (see set), hitting the <tab> key twice accomplishes the same thing.

nym 

Yank text block into the delete buffer. Does not alter the command line or cursor position, but makes the text block available to subsequent put (p or P) commands. If n is given, it is applied to the movement.

yy 

Yank entire command line.

Y 

equivalent to y$ -- yank rest of line.

# 

Equivalent to I#ENTER.

nv 

Execute fc -e ${VISUAL:-${EDITOR:-vi}} n. If n is omitted, the history number of the current line is used.

CTRL-L 

Re-display the current line.

CTRL-J 
CTRL-M 
ENTER 

Execute the current line.


EXAMPLES

Software distributed over computer networks such as Usenet is often distributed in a form known as a shell archive. In essence, a shell archive is a shell script containing the data of one or more files, plus commands to reconstruct the data files and check that the data was transmitted correctly. The following shows a sample shell archive, and demonstrates the use of a here document:

# This is a shell archive.
# It contains the one file "frag.ksh"
# To extract contents, type
# sh file
#
if	[ -f frag.ksh ]
then	echo frag.ksh exists: will not overwrite
else
	echo extracting frag.ksh
	sed 's/^X//' >frag.ksh <<_EOF_
X# This is frag.ksh
X# Not very interesting, really.
Xecho frag.ksh here!
_EOF_
    	if [ "`sum frag.ksh|awk '{print $1}'`" != 52575 ]
    	then	echo frag.ksh damaged in transit
    	fi
fi

The following simple script produces as much of the Fibonacci sequence as can be calculated using integers:

# Print out Fibonacci sequence; start sequence
# with first two positional parameters:
# default 1 1
typeset -i x=${1:-1} y=${2:-1} z
while	[ x -gt 0 ]	# until overflow
do
	echo $x
	let z=y+x x=y y=z
done

The following implements the basename utility as a shell function:

# basename utility as shell function
function basename {
	case $# in
	1)	;;
	2)	eval set \${1%$2} ;;
	*)	echo Usage: $0 pathname '[suffix]'
		return 1 ;;
	esac
	echo ${1##*/}
	return 0
}

ENVIRONMENT VARIABLES

_ 

(underscore) expands to the last argument of the previously executed command. For every command that is executed as a child of the shell, sh sets this variable ($_) to the full path name of the executable file and passes this value through the environment to that child process.

When processing the MAILPATH variable, $_ holds the value of the corresponding mail file.

BASH 

is set when the shell is invoked with the bash command or when set -o bash (or the equivalent) is executed. It contains the full path to the shell executable.

If this variable is set and set +o bash or set -o korn is executed, its value remains set even though the shell is no longer in bash made.

BASH_ENV 

contains a value on which the shell performs parameter substitution and uses the result as the name of an initialization file. This file is executed with the . command. This facility lets you define functions (see Command Syntax), aliases (see alias) and other non-exported items during shell initialization.

The file specified by this variable is only used when the shell is started in bash mode.

BASH_VERSION 

is set when the shell is invoked with the bash command or when set -o bash (or the equivalent) is executed. This readonly array contains version information for the shell. The array has the following members:

BASH+VERSION[1]	major version number
BASH+VERSION[2]	minor version number
BASH+VERSION[3]	patch level
BASH+VERSION[4]	build number
BASH+VERSION[5]	release status
BASH+VERSION[6]	the value of the MACHTYPE environment variable

If this variable is set and set +o bash or set -o korn is executed, its value remains set even though the shell is no longer in bash made.

CDPATH 

contains a list of directories for the cd command to search. Directory names are separated with colons on POSIX and UNIX systems, semicolons on Windows systems. CDPATH works in a similar way to the PATH variable.

COLUMNS 

contains the maximum width of the edit window in the KornShell vi or emacs editing modes. It is also used by several other commands to define the width of the terminal output device.

DUALCASE 

when set, makes pattern-matching in case statements and file name generation case-sensitive. By default, DUALCASE is not set and as a result, pattern-matching in file name generation is case-insensitive and the setting of TK_DUALCASE_IN_CASE_STATEMENTS determines whether or not pattern-matching in case statements is case-sensitive.

DUALCASE also affects an interactive shell's completion feature.

EDITOR 

enables the corresponding editing mode (see Command Line Editing) when using vi, emacs, or gmacs. If VISUAL is also set, its value takes precedence over EDITOR's.

ENV 

contains a value on which sh performs parameter substitution and uses the result as the name of an initialization file. This file is executed with the . command. This facility lets you define functions (see Command Syntax), aliases (see alias) and other non-exported items during shell initialization.

ERRNO 

contains the system error number of the most recently failed system call. The shell only sets this variable for errors which occur in the current environment. Assigning a value of 0 to this variable clears it.

FCEDIT 

contains the path name of the default editor for the fc command. If this variable is not set, the default is the ed command.

FIGNORE 

has its contents interpreted in two different ways depending on what mode the shell is operating in.

In ksh mode or in the default sh mode, FIGNORE contains a pattern which determines files that are to be ignored during file expansion. For example, suppose a directory contains:

file.c   file.o   file1.c  file1.o  file2.c  file2.o

To ignore all files with a .o extension, you do the following:

$ FIGNORE='*.o'
$ ls
file.c   file.o   file1.c  file1.o  file2.c  file2.o
$ ls *
file.c   file1.c  file2.c

Note that since the first ls does no file name expansion, it still displays the .o files; however the second ls command uses file name expansion and hence ignores those files.

In bash mode, FIGNORE is a semicolon-separated lists of patterns not to match when expanding wild cards during file name generation.

FPATH 

contains a semicolon-separated list of directories to search for function definitions when an undefined function is executed.

Additionally, if this variable is defined and a PATH search fails to locate a command named cmdname, the directories specified in this variable are searched directory by directory for a space named cmdname.ksh or if that is not found, a script named cmdname. If such a script is found, it is executed in the current shell environment. Once that script has executed, the function cmdname, whose definition should have been included in the executed script, is now executed. If the function cmdname is still undefined, an error results.

For a full description of undefined functions and the autoload alias, see the functions reference page.

FUNCNAME 

is a read-only environment variable that contains the name of the function currently being executed when the shell is in bash mode. When execution of the function is complete, this variable is reset to its previous value, if any.

When the shell is not in bash mode, this variable is not set.

FUNCTION 

when the TK_SH_SET_FUNCTION_VARIABLE is set, this variable contains the name of the function currently being executed or if a function is not being executed, it contains the value of $0.

The FUNCTION environment variable is particularly useful in conjunction with the PS4 environment variable as can be seen in teh following example:

export TK_SH_SET_FUNCTION_VARIABLE=1
PS4='<$FUNCTION:$LINENO> '
set -x
function func
{
	echo inside function $FUNCTION
}
echo $0
func
GLOBIGNORE 

contains a semicolon-separated list of patterns not to match when expanding wild cards during path name generation when the shell is in bash mode.

When GLOBIGNORE is set, -o dotglob behavior is automatically enabled. In such a case, if you do not want wild cards to match file names that start with ., add .* to GLOBIGNORE.

HASHBANG 

enables or disables the #! feature of the MKS KornShell. If this variable is set to a non-zero value, the feature is enabled; otherwise, it is disabled. See the Command Execution section for more details.

HISTCMD 

is set by the MKS KornShell to contain the number of the current command in the history file.

HISTCONTROL 

in bash mode, determines whether or not a command is stored in the history file.

HISTCONTROL has three meaningful values:

ignorespaces 

Commands starting with a space or tab character are not stored in the history file.

ignoredups 

Any command that is identical to the previous command is not stored in the history file.

ignoreboth 

Neither commands that start with a space or tab character nor those that are identical to the previous command are stored in the history file.

When HISTCONTROL is not set or is set to a value other than those listed, all commands are stored in the history file.

HISTEDIT 

contains the path name of the default editor for the hist command. If this variable is not set, hist uses the editor indicated by the FCEDIT environment variable. Finally, if neither of these variables are set, it uses the ed command.

HISTFILE 

contains the path name of a file to be used as the history file. When the shell starts, the value of this variable overrides the default history file. See FILES.

HISTSIZE 

contains the maximum number of commands that the shell keeps in the history file. If this variable contains a valid number when the shell starts, it overrides the default. In bash mode, the default is 500; otherwise, the default is 128.

HOME 

contains your home directory. This is the default directory for the cd command.

HOSTNAME 

is set when the shell is invoked with the bash command or when set -o bash (or the equivalent) is executed. This variable contains the name of the current host machine as determined by uname -n.

If this variable is set and set +o bash or set -o korn is executed, its value remains set even though the shell is no longer in bash made.

HOSTTYPE 

is set when the shell is invoked with the bash command or when set -o bash (or the equivalent) is executed. This variable contains the type of the current host machine as determined by uname -m.

If this variable is set and set +o bash or set -o korn is executed, its value remains set even though the shell is no longer in bash made.

IFS 

contains a series of characters to be used as internal field separator characters. During word expansion (see Word Expansion), the presence of any of these characters within a word causes it to be split. In addition, the shell uses these characters to separate values put into variables with the read command. Lastly, the first character in the value of IFS separates the positional parameters in $* expansion. By default, IFS contains space, tab, and newline.

Note:

Using the unset on this environment variable does not remove it from the environment. It restores the variable to its default value of space, tab, and newline.

LINENO 

contains the number of the line currently being executed by a shell script.

LINES 

contains a numeric value that limits the number of output lines used by the select statement in printing its menu.

MACHTYPE 

is set when the shell is invoked with the bash command or when set -o bash (or the equivalent) is executed. This variable contains a string describing the system type on which the shell is running. This string is defined as "$PROCESSOR_ARCHITECTURE-MKS-$OSTYPE".

If this variable is set and set +o bash or set -o korn is executed, its value remains set even though the shell is no longer in bash made.

MAIL 

contains the path name of a mailbox. If MAILPATH is not set, the MKS KornShell tells you when new mail arrives in this file. The shell assumes that new mail has arrived if the file's modify time changes.

MAILCHECK 

contains the number of seconds of elapsed time that must pass before checking for mail; if not set, the default value is 600 seconds. When using the MAIL or MAILPATH variables, the MKS KornShell checks for mail before issuing a prompt.

MAILPATH 

contains a list of mailbox files. This overrides the MAIL variable. The mailbox list is separated by colons on POSIX and UNIX systems, and by semicolons on Windows systems. If any name is followed by ?message or %message, sh displays the message if the corresponding file has changed. sh performs parameter and command substitution on message and the variable _ (temporarily) expands to the name of the mailbox file. If no ?message or %message is present, the default message is you have mail in $_..

OLDPWD 

contains the path name of the previous directory. The cd command sets this variable.

OSTYPE 

is set when the shell is invoked with the bash command or when set -o bash (or the equivalent) is executed. This variable contains the name of the operating system on which the shell is running as determined by uname -s.

If this variable is set and set +o bash or set -o korn is executed, its value remains set even though the shell is no longer in bash made.

PATH 

contains a list of directories which constitute the search path for executable commands. Directories in this list are separated with colons on POSIX and UNIX systems, and by semicolons on Windows systems. sh searches each directory in the order specified in the list until it finds a matching executable. If you want the shell to search the current directory, put a null string in the list of directories (for example, starting the list with a colon/semicolon tells the shell to search the current directory first).

PATHEXT 

contains a list of file extensions (separated by semicolons) for executable commands. Matching files with these extensions are searched for when the exact command name is not found. As the shell searches each directory in the search path, it appends each of the extensions in the list, in turn, to the command name and if it matches a file name in that directory, that file is executed as though it had that extension.

By default, PATHEXT, has the value of 8.1/2012R2/10/2016/2019/11/2022's PATHEXT variable with .com;.exe;.bat;.sh;.ksh;.csh;.sed;.awk;.pl appended (omitting any extensions already represented in PATHEXT).

PPID 

contains the decimal value of the process ID of the parent of the shell.

POSIXLY_CORRECT 

determines whether or not sh is running in 'pedantic posix' mode or not. If this environment variable is set, the shell behaves as though the -o posix option had been specified. Unsetting this environment variable is the equivalent of specifying set +o posix to turn off the 'pedantic posix' mode.

POSIX_PEDANTIC 

is similar to POSIXLY_CORRECT, but affects only the shell on startup if POSIXLY_CORRECT is not set. This environment variable allows you to have 'pedantic posix' mode off in your current shell, but have it turned on in any subshells that you spawn.

PS1 

contains the primary prompt string used when the shell is interactive. The default value is a dollar sign followed by a space ($ ). The shell expands parameters before the prompt is printed. A single exclamation mark (!) in the prompt string is replaced by the command number from the history list (see fc); for a real exclamation mark in the prompt, use !!.

The prompt strings contained in the PS1, PS2, PS3, and PS4 environment variables can contain the following backslash sequences:

\a		bell
\e		escape character (ESC)
\E		escape character (ESC)
\n 		newline
\r 		carriage return
\NNN 		the character whose octal value is NNN
\# 		the value of $HISTCMD
\! 		the value of $HISTCMD
\$ 		# if the effective user id is 0 else it is replaced by $
\j 		the number of currently running background jobs
\l 		the name of the terminal device
\s 		the basename of the name of the shell
   		(if this a login shell then this name starts with -)
\v		the version number of the shell
\V 		the release number of the shell
\w 		the value of $PWD
\W 		the basename of $PWD
\u 		the value of $LOGNAME
\h 		`uname -n`
\H		`uname -n`
\d 		`date +"%a %b %d"` 
\t 		`date +"%H:%M:%S"`
\T		`date +"%I:%M:%S"`
\@ 		`date +"%I:%M %p"`
\A 		`date +"%H:%M"`
\D{format}		`date +"format"`

In addition, these prompt strings can also contain the following escape sequences (beginning with \033, the escape character) surrounded by \[ and \]:

\\ 			causes \ to be displayed
\033]number;string\00	sets string as the title of the window
			(and number is discarded; it is supported for
			compatibility with bash)
\033]string\007 		sets string as the title of the window
\033[0m			sets the foreground and background colours to what was
			set before the prompt string was displayed, and turns
			off 'reverse', 'underline', 'conceal', 'bold foreground'
			and 'bold background'.
\033[1m 			turns on 'bold foreground'
\033[4m 			turns on 'underline' (cyan)
\033[5m 			turns on 'bold background'
\033[7m 			turns on 'reverse' (foreground and background colours are
			swapped; this also applies to the colours when they are set)
\033[8m 			turns on 'conceal' (when non-bold the foreground colour is
			black, when bold the foreground colour is bold white)
\033[30m 			sets foreground colour to black
\033[31m 			sets foreground colour to red
\033[32m 			sets foreground colour to green
\033[33m 			sets foreground colour to yellow
\033[34m 			sets foreground colour to blue
\033[35m 			sets foreground colour to cyan
\033[36m 			sets foreground colour to purple
\033[37m 			sets foreground colour to white
\033[40m 			sets background colour to black
\033[41m 			sets background colour to red
\033[42m 			sets background colour to green
\033[43m 			sets background colour to yellow
\033[44m 			sets background colour to blue
\033[45m 			sets background colour to cyan
\033[46m 			sets background colour to purple
\033[47m 			sets background colour to white
\033[X1;X2;...;X20m 	is the equivalent of \033[X1m\033[X2m...\033[X20m

For example:

PS1='\[\033]0;$PWD\007\033[1;33m\]$\[\033[0m\] '

sets the window title to the current directory, and the prompt to a bright yellow $.

PS2 

contains the secondary prompt, used when completing the input of such things as reserved word commands, quoted strings, and here documents. The default value of this variable is a greater than sign followed by a space (> ).

This string can contain the backslash and escape sequences described for PS1.

PS3 

contains the prompt string used in connection with the select reserved word. The default value is a number sign followed by a question mark and a space (#? ).

This string can contain the backslash and escape sequences described for PS1.

PS4 

contains the prefix for traced commands with set -x. The default value is a plus sign followed by a space (+ ).

This string can contain the backslash and escape sequences described for PS1.

PWD 

contains the path name of the current working directory. When the shell starts, the current directory name is assigned to PWD unless the variable already has a value.

RANDOM 

expands to a random integer. Assigning a value to RANDOM sets a new seed for the random number generator.

REPLY 

contains the user input from the select statement (see Command Syntax). The read command also sets this variable if no variable is specified.

SECONDS 

contains elapsed time. The value of this variable grows by 1 for each elapsed second of real time. Any value assigned to this variable sets the SECONDS counter to that value; initially the shell sets the value to 0.

SHELL 

contains the full path name of the current shell. It is not set by the shell, but is used by various other commands such as awk, vi, and ed, that have the ability to call a shell to run a command and then return to the program. They use the SHELL variable to find the shell to be run, or if that is not defined, the COMSPEC (or ComSpec) variable. See the envvar reference page for details on the COMPSPEC (or ComSpec) environment variable.

SHELL_ELEVATED 

is set to 1 on shell start-up when the shell has been elevated to "run as Administrator".

When SHELL_ELEVATED is non-zero, the shell is elevated, and the environment variable TITLEBAR is not set, the word Elevated is preprended to the default titlebar string.

SHELL_ERASE 
SHELL_INTR 
SHELL_KILL 

define new values on Windows systems for the erase, interrupt, and line delete characters, respectively. The value of each of these variables is a single character which is ANDed with 0x1f to get a control character. For example:

SHELL_ERASE=x

sets the erase character to CTRL-X. The new erase, interrupt, and line delete characters are only in effect when using the shell command line in editing mode or the vi editor.

Note:

Setting the SHELL_INTR environment variable does not stop the shell from responding to CTRL-C, since CTRL-C is processed by the console. However, the character defined by SHELL_INTR is now handled in the same manner. As well, since the SHELL_INTR value is only used by the shell command line and vi, you must still use CTRL-C to interrupt any of the programs being run.

SHELL_VERSION 

contains the version followed by the build date of the MKS KornShell. For example, if this variable contains:

6.2 build 639 Apr 28 1999 10:28:11

you are using build number 639 of version 6.2 of the MKS KornShell which was built on April 28, 1999 at 10:28:11.

SHLVL 

is set when the shell is invoked with the bash command or when set -o bash (or the equivalent) is executed. This variable contains the current nesting level of your shell scripts .

If this variable is set and set +o bash or set -o korn is executed, its value remains set even though the shell is no longer in bash made.

SHPATHEXT 

contains a list of file extensions (separated by semicolons) for executable commands. Matching files with these extensions are searched for when the exact command name is not found. As the shell searches each directory in the search path, it appends each of the extensions in the list, in turn, to the command name and if it matches a file name in that directory, that file is executed as though it had that extension.

By default, SHPATHEXT is unset.

If both SHPATHEXT and PATHEXT are set, the shell checks SHPATHEXT first.

TITLEBAR 

sets the window title when running the shell under Windows. The default title of MKS Korn Shell is overridden by setting:

TITLEBAR=new title

Keyword expansion is performed on the string new title if possible, so that you can enter a setting such as:

TITLEBAR='$PWD'

to display the current working directory as the title of the window. To return to the default title, set TITLEBAR to an empty string.

TK_CMDSUB_FORMAT 

Contains the format to be used for the output from command substitution in MKS KornShell (the `command_line` and $(command_line structures). The value must be one of those listed in the File Character Formats section of the unicode reference page.

When TK_CMDSUB_FORMAT is not set, the value of the TK_STDIO_DEFAULT_INPUT_FORMAT environment variable is used as the default format.

When TK_CMDSUB_FORMAT and TK_STDIO_DEFAULT_INPUT_FORMAT are both unset, either ASCII_OEM or ASCII_ANSI is used as the default format, as dictated by the current code page. This provides compatibility with older versions of MKS Toolkit.

TK_DO_NOT_PROCESS_ARG_QUOTING 

when set to a non-zero value, disables additional processing of arguments beyond the standard shell quoting. This lets you pass active quotes to a program without them being escaped and becoming literal quotes.

TK_DO_NOT_RUN_WITH_REG_ASSOCIATIONS 

When set, sh ignores file associations in the registry when determining how to run a file.

TK_DUALCASE_IN_CASE_STATEMENTS 

when set, makes pattern-matching in case statements case-sensitive. By default, TK_DUALCASE_IN_CASE_STATEMENTS is not set, and the setting of DUALCASE determines whether or not pattern-matching in case is case-sensitive.

TK_FILENAME_COMPLETION 

when set to a valid value, this variable overrides the DUALCASE environment variable with respect to file name completion. Vaild values are case sensitive and case insensitive.

TK_GUI_ON 

when set to 0, shell errors are sent to standard error and all GUI features are turned off for the running shell. This is the equivalent of specifying -G on the sh command line.

TK_HASHBANG_DO_NOT_SEARCH_PATH 

When set to a non-zero value, and the command in:

#![command] [arguments]

cannot be found, the shell does not attempt a path seach on the basename of command.

TK_HEREDOC_FORMAT 

Contains the format to be used for here documents. The value must be one of those listed in the File Character Formats section of the unicode reference page.

When TK_HEREDOC_FORMAT and TK_STDIO_DEFAULT_OUTPUT_FORMAT are both unset, here documents are assumed to use ASCII_OEM characters. This provides compatibility with older versions of MKS Toolkit.

When TK_STDIO_DEFAULT_OUTPUT_FORMAT is set to UNICODE_BIG_ENDIAN, UNICODE_LITTLE_ENDIAN, UNICODE, UTF8, or UTF-8 and you are feeding a here document to a non-MKS Toolkit utility that won't understand its format, you should set TK_HEREDOC_FORMAT to ASCII_OEM and export it.

When TK_HEREDOC_FORMAT is unset or TK_STDIO_DEFAULT_OUTPUT_FORMAT is set to ASCII, ASCII_OEM, or ASCII_ANSI and your here document contains non-ASCII (OEM) characters, you should set TK_HEREDOC_FORMAT to UTF8 and export it.

This variable takes precedence over TK_STDIO_DEFAULT_OUTPUT_FORMAT.

TK_INTERACTIVE_GUI_COMMAND_IN_BACKGROUND 

When set, external GUI utilities, such as viw and vpax automatically run in the background when started from the MKS KornShell command line. However, if the environment variable TK_GUI_SUBSYSTEM_NOT_SUPPORTED is set, such GUI utilities will not be run at all.

TK_PATH_CONVERT 

Determines whether or environment variables that are considered to contain path names are displayed in Windows or UNIX format. When this variable is set to UNIX (this value is case-insensitive), such an enivronment variable is displayed in UNIX format; otherwise, it is displayed in Windows format. See the Environment Variables and Paths section of the EUCM reference page for more information.

TK_SH_DISPLAY_COMMANDS_IN_SCRIPTS 

when set, the title bar of the shell's window displays the command line for each non-built-in utility in a shell script as it is executed. When this variable is unset, such command lines are only displayed when the shell is interactive.

TK_SH_EXPORT_FUNCTIONS_TO_NONSUBSHELLS 

when set, shell functions are exported to a nonsubshell in such a way that the function definitions are passed through to any shells called by the nonsubshell.

TK_SH_GUI_ON 

when set, the GUI features of the MKS KornShell are enabled. When it is not set, the the GUI features are disabled. By default, this variable is set; however, if the shell was started with the -G option, this variable is unset.

TK_SH_RHS_OF_PIPE_IN_CURRENT_SHELL 

when set, the right hand side of a pipe is executed in the current shell. Normally, the right hand side is executed in a subshell.

TK_SH_SET_FUNCTION_VARIABLE 

when set, sets the FUNCTION to the function name if a function is currently being executed or to $0 if no function is currently being executed.

TK_SUFFIXED_SEARCHING_FIRST 

By default, MKS Toolkit utilities first search for a command exactly as typed by the user, and if not found, then search for it using file name extensions as described in the Command Execution section of this reference page.

When the TK_SUFFIXED_SEARCHING_FIRST environment variable is set, this process is reversed. The command is first searched for using file name extensions and then, if not found, it is searched for exactly as typed by the user.

Consider the following:

echo "echo search_test" > search_test
echo "echo search_test.ksh" > search_test.ksh
PATH="$PATH;"
unset TK_SUFFIXED_SEARCHING_FIRST
search_test
export TK_SUFFIXED_SEARCHING_FIRST=1
search_test
unset TK_SUFFIXED_SEARCHING_FIRST
search_test

The output from the above is:

search_test
search_test.ksh
search_test
TK_UNIX_FILESYSTEM 

When this variable is set, the Enhanced UNIX Compatibility Mode is on and the virtual file system is in use. For more information, see the EUCM reference page.

TK_USE_CTRLD_AS_CONSOLE_EOF 

When set, allows the use of CTRL-D as the EOF (end-of-file) character for the MKS KornShell (including sh, bash, ksh and resh) and MKS C Shell as well as for any utility that can accept input from the console.

Also, for the MKS KornShell, when set, this variable allows CTRL-D at the start of a line to terminate an interactive shell.

TMOUT 

contains the number of seconds before user input times out. If user input has not been received within this length of time, the shell terminates.

VISUAL 

overrides the EDITOR variable in setting vi, emacs, or gmacs editing modes (see Command Line Editing).


FILES

sh_history 

default history storage file

$HOME/profile.ksh 

profile for login shell

ROOTDIR/etc/profile.ksh 

system-wide profile for login shells

/tmp/sh* 

Temporary files for here documents, command substitution, history re-execution, etc. The default directory /tmp can be overridden by setting the shell variable TMPDIR to the name of some other directory. See the envvar reference page.


DIAGNOSTICS

Possible exit status values are:

0 

Successful completion.

1 

Failure due to any of the following:

— shell is invoked with an invalid option
— shell is invoked to run a shell script and the command to run the script had a command syntax error
— a redirection error
— variable expansion error

128 

sh called a program that crashed.

>128 

sh, or a program that sh called, was interrupted by a signal; the error code is the signal number OR'ed with 128. For example, SIGINT ( CTRL-C) is frequently signal 2: the return code from sh; is 128|2, or 130.

134 

sh called a program that aborted. The program signals that it aborted by using a negative return code that doesn't correspond to one of the predefined Windows-specific negative return codes.

Otherwise, the exit status of the shell defaults to the exit status of the last command executed by the shell. This default may be overridden by explicit use of the exit or return commands. The exit status of a pipeline is the exit status of the last command in the pipeline.

Most diagnostics are self explanatory. See the command reference pages for diagnostics from built-in commands.

Ambiguous redirection 

A redirection construct expanded to more than one path name.

File "file" already exists 

You are attempting to redirect output into an existing file, but you have turned on the noclobber option (see set). If you really want to redirect output into an existing file, use the construct >|filename, or turn off the option with:

set +o noclobber
File descriptor number already redirected 

You attempted to redirect a file descriptor that was already being redirected in the same command. You can only redirect a file descriptor once.

Hangup 

The shell received a hangup signal. This signal typically arises when a communication line is disconnected (for example, when a phone connection is cut off). When the shell receives a hangup signal, it sends a hangup signal to all process groups, foreground and background, and then exits.

In base#number: base must be in [2,36] 

In a number with the form base#number, the value of the base was larger than 36 or less than 2. The only valid range for bases is from 2 through 36.

Invalid subscript 

A shell array was indexed with a subscript outside the defined bounds.

Illegal instruction 

The shell received an illegal instruction signal. This typically occurs when a process tries to execute something that is not a valid machine instruction recognized by the hardware.

Misplaced subscript "array name

The subscript for an array was missing or invalid.

Name is not an identifier 

You attempted to use a non-alphanumeric Name.

Name: readonly variable 

The given Name is a read-only variable and cannot be removed or changed (see readonly).

Name: no expansion of unset variable 

The shell is operating with set -u and you used an unset variable in a substitution. For more information, see set.

No file descriptor available for redirection 

When a file descriptor is redirected, the shell remembers the old value by duplicating it to another file descriptor. Since the total number of file descriptors is limited by the system, the shell may run out of descriptors while it looks like your command is using far fewer than the maximum number allocated.

...: restricted 

If the shell has been invoked as a restricted shell, certain things are disallowed (for example, the cd command, setting PATH, and output redirection).

Temporary file error using here document 

sh tried to create a temporary file to hold the contents of a <<word here document, but the temporary file could not be created. This may indicate a lack of space on the disk where temporary files are created.


PORTABILITY

POSIX.2. x/OPEN Portability Guide 4.0. Windows 8.1. Windows Server 2012 R2. Windows 10. Windows Server 2016. Windows Server 2019. Windows 11. Windows Server 2022. Upwardly compatible with the Bourne Shell on UNIX systems.

Extensions to POSIX

The following items are extensions to the POSIX standard that come from the KornShell:

The restricted shell and invocation option -r are from SVID and the KornShell.

The construct $[arithmetic expression] is an extension to the POSIX standard.

Much of the functionality of the KornShell comes from built-in commands such as cd and alias. The reference pages for such commands describe additional features of the shell not included here.

Differences From UNIX

The MKS Toolkit version of sh is based on the Korn, Bourne-Again, and POSIX.2 shells found on many UNIX systems. While sh offers most of the functionality of these shells, there are some differences, largely due to differences between Windows and ux; systems.

File Names

All Windows systems use roughly the same techniques for dealing with files; however, different Windows operating systems actually use different file systems. Windows 95/98/Me used the extended FAT file system, while 8.1/2012R2/10/2016/2019/11/2022 uses a file system called NTFS. Because the file systems are implemented in the same way regardless of the native platform, the following paragraphs concentrate on the particular file systems.

The most obvious difference between UNIX file systems and the Windows file systems is the naming of files. This is a result of the standards employed by the different operating systems, and cannot be hidden by the shell.

File names in the NTFS and extended FAT file systems may contain up to 254 characters. UNIX file names, on the other hand, can be up to 14 characters in length (or more on some systems), and may contain any characters except slash (/) and null. A dot is not considered special in any way in a UNIX file name.

On NTFS and extended FAT file systems, the case of file names is preserved for cosmetic reasons, but ignored. UNIX systems, on the other hand, respect the difference between upper and lowercase. On UNIX systems therefore, the name MyFile is refers to a different file than the name myfile, but on the NTFS and extended FAT file systems, both names refer to the same file.

On NTFS and extended FAT file systems, the PTC MKS Toolkit commands display file names as returned by the operating system. Thus, given a file called DataFile, ls returns DataFile as the file name. However, you can refer to this file as any of: datafile, dataFile, DATAFILE, DaTafIle, and so on. Wildcard expansion ignores case by default on the NTFS and extended FAT file systems. You can override this (and force wildcard expansion to respect case as you type it) by setting the DUALCASE environment variable to any value.

Some of the standard files used by the UNIX shells have different names on Windows systems running the MKS Toolkit. These PTC MKS Toolkit file names were originally created for older FAT file systems (which placed more limits on file names) and for consistency with earlier versions of tk;, these names are still used for the NTFS and extended FAT file systems. Table 3 shows some of these files along with the file names used by both UNIX systems and PTC MKS Toolkit:

UNIX name MKS Toolkit name

.profile profile.ksh
.sh_history sh_histo
/etc/profile /etc/profile.ksh

Table 3: File Name Translations: UNIX to PTC MKS Toolkit

Path Names

The UNIX file system and both Windows file systems are tree-structured file systems, where you can create directories and subdirectories to organize the files. However, UNIX utilities use the slash (/) to separate directory names, while cmd.exe uses the backslash (\) for the same purpose.

The sh utility and all MKS Toolkit utilities launched from that shell use slashes to separate directories. You can also use the backslash to separate directories; however, because the backslash is a special character to sh, you must quote it (for example, by preceding it with another backslash, as in \\). For details on quoting characters and strings, see Quoting earlier in this reference page.

Delimiters Within Path Lists

When specifying a list of path names on UNIX systems (in the PATH environment variable, for example), it is customary to separate them with colons (:). However, because the colon is a legal part of a path name on Windows systems, as in c:/bin, it cannot be used as a separator. Instead, the semicolon (;) is used.

This affects the path name lists used for the environment variables PATH, CDPATH, and MAILPATH. Thus, if you are copying a list of path names from a UNIX system to a Windows system, be sure you are using the correct delimiters.

For example, the path name list:

/bin:/usr/bin

that might be used on UNIX systems has to be changed to:

/bin;/usr/bin

You may also have to add drive letters to the path name list, so it might become:

c:/bin;c:/usr/bin

When typing a path list containing semicolons, remember to quote the line, because the semicolon is treated specially by the shell, and the quoting removes its special meaning.

Including the Current Directory in the Path

When you enter a command that causes a program to be run, there are several places where that program could be located on the disk. The PATH environment variable allows you to specify where the native command interpreter or sh should look to find programs. However, there are slight differences between the KornShell and the 8.1/2012R2/10/2016/2019/11/2022 command interpreters.

cmd.exe (on 8.1/2012R2/10/2016/2019/11/2022) starts by looking in the current directory for a program. If the program is not found there, the native command interpreter looks in each of the directories specified in the PATH environment variable (Path under 8.1/2012R2/10/2016/2019/11/2022).

The sh utility, on the other hand, looks only in the directories specified in the PATH environment variable. You must explicitly tell it to look in the current directory, if that is desired. To do this, include a null entry in the path name list in the PATH environment variable.

For example, given the path list:

/bin;/usr/bin

cmd.exe looks in the current directory, then in /bin, then in /usr/bin, stopping as soon as it finds the program. Given the same path list, sh only looks for the program in /bin and /usr/bin.

When using sh, the current directory is represented by the null path. Thus, if you change the path list to:

;/bin;/usr/bin

sh behaves the same as cmd.exe. The null string before the first semicolon represents the current directory.

However, you could have the current directory searched second, or last, or never. As examples, consider the lists:

/bin;;/usr/bin
/bin;/usr/bin;

In the first one, the current directory is listed between the two semicolons, so it is searched after /bin but before /usr/bin. In the second, the current directory is listed after the second semicolon, so it is searched last.

You can also represent the current directory by a dot (.). For example, consider the two paths listed in the previous paragraph:

/bin;.;/usr/bin
/bin;/usr/bin;.

Length of Command Lines

There is a maximum length that commands may not exceed. The limiting factor is the lengths of the various buffers that hold your command. A command can be only as long as the shortest buffer it passes through. There is the buffer that holds your keystrokes until you press the ENTER key, the buffer within the command interpreter or shell, and the buffer with the program being run.

The command line limit on Windows systems is currently 32K.

Exporting of Environment Variables

When defining shell variables, sh lets you specify whether the variables are put into the environment that is passed to any programs invoked by the shell. In cmd.exe, all shell variables are passed to programs. There is no choice. When using sh, variables are NOT passed unless that is specified. This process of passing variables is called exporting, because they are exported from the shell to the invoked program. In particular, note that you should export the PATH variable (for consistency, cmd.exe under 8.1/2012R2/10/2016/2019/11/2022 accepts both PATH and Path).

If you have problems with a program that works well under cmd.exe but fails to work under the KornShell, check that all the necessary environment variables are being exported.

For details on this, see the export, set, and sh reference pages.

The total size of all exported variables is limited to 32K.

Device Error Handling

If your operating system encounters a problem with a disk drive or the printer, a `critical error' is generated. This causes the offending program to run a special piece of code to handle the error.

If the program was started by cmd.exe, the following message (or something like it) is displayed and you have to decide how it is to be handled:

Error on drive A
Abort, Retry, Ignore

Since the KornShell attempts to emulate UNIX systems, programs running under it do not display this message when a critical error occurs. Instead, the critical error handler returns an error code to the program. In most instances, the program then displays an error message and terminates.


LIMITS

The size of the command argument and exported variables passed between the shell and the utilities it runs depends upon the operating system. Because the shell has no way of knowing the type of command it is calling, it performs two expansions.

The first expansion is placed in a non-standard location where it is read by all PTC MKS Toolkit utilities. For Windows systems, the environment is used, which restricts the amount of memory available to the shell.

The second expansion is performed for commands which need their command arguments passed directly to them. This second expansion is restricted by the limits of the native command interpreters (32K on Windows systems).

On Windows systems, the environment space is limited to 32K. If you exceed this limit, the system returns an error such as:

cannot execute: More data is available

The maximum length of an executable file name, including subdirectories and extensions, depends upon the operating system. See your Windows system documentation for specific restrictions on file names.

The command line length limit on Windows systems is currently 32K.

The total size of all exported variables on Windows systems is limited to 32K.


NOTES

Normally, MKS KornShell variable names can only contain alphanumeric characters and the underscore (_), and cannot begin with a digit; however, some applications require a shell variable to be set that does not follow these naming conventions. To set such a variable, you can use the env command to insert the normally invalid name directly into the environment block. For example, to run a program that requires a variable named 386 to be set to yes, you can use the following command:

env '386=yes' program

64-BIT NOTE

PTC MKS Toolkit for Enterprise Developers 64-Bit Edition includes both 32-bit and 64-bit versions of sh. When you install this product, the correct version is installed. The two versions are identical except that the 64-bit version allows attempts by the shell (and utilities run from it) to access the %systemroot%\system32 directory to actually access that directory. Attempting to access the %systemroot%\system32 directory by other shells or command interpreters (and utilities run from them) on 64-bit Windows platforms may result in the %systemroot%\SysWOW64 directory being accessed instead.


AVAILABILITY

PTC MKS Toolkit for Power Users
PTC MKS Toolkit for System Administrators
PTC MKS Toolkit for Developers
PTC MKS Toolkit for Interoperability
PTC MKS Toolkit for Professional Developers
PTC MKS Toolkit for Professional Developers 64-Bit Edition
PTC MKS Toolkit for Enterprise Developers
PTC MKS Toolkit for Enterprise Developers 64-Bit Edition
PTC Windchill Requirements and Validation


SEE ALSO

Commands:
alias, basename, break, cd, chmod, continue, date, dirname, dlg, dot, echo, eval, exec, exit, export, false, fc, functions, getopts, history, jobs, kill, let, mkdir, mks_env, print, ps, pwd, r, read, readonly, return, rm, rmdir, set, shift, shopt, test, time, times, touch, trap, true, typeset, unalias, uname, unset, whence

Miscellaneous:
envvar, unicode

Using the MKS KornShell


PTC MKS Toolkit 10.4 Documentation Build 39.