ksh, rksh - KornShell, a standard/restricted command and programming language
/usr/bin/ksh [± abCefhikmnoprstuvx] [± o option]... [arg]...
/usr/bin/ksh -c [± abCefhikmnoprstuvx] [± o option]... command_string [command_name [arg...]]
/usr/xpg4/bin/sh [± abCefhikmnoprstuvx] [± o option]... [arg]...
/usr/xpg4/bin/sh -c [± abCefhikmnoprstuvx] [± o option]... command_string [command_name [arg...]]
/usr/bin/rksh [± abCefhikmnoprstuvx] [± o option]... [arg]...
/usr/bin/rksh -c [± abCefhikmnoprstuvx] [± o option]... command_string [command_name [arg...]]
The /usr/xpg4/bin/sh utility is a standards compliant shell. This utility provides all the functionality of /usr/bin/ksh, except in cases where differences in behavior exist. See Arithmetic Expansions section for details.
/usr/bin/ksh is a command and programming language that executes commands read from a terminal or a file. rksh is a restricted version of the command interpreter ksh; it is used to set up login names and execution environments whose capabilities are more controlled than those of the standard shell. See the Invocation section for the meaning of arguments to the shell.
A metacharacter is one of the following characters:
; & ( ) | < > NEWLINE SPACE TAB
A blank is a TAB or a SPACE. An identifier is a sequence of letters, digits, or underscores starting with a letter or underscore. Identifiers are used as names for functions and variables. A word is a sequence of characters separated by one or more non-quoted metacharacters.
A command is a sequence of characters in the syntax of the shell language. The shell reads each command and carries out the desired action either directly or by invoking separate utilities. A special-command is a command that is carried out by the shell without creating a separate process. Except for documented side effects, most special commands can be implemented as separate utilities.
A simple-command is a sequence of blank-separated words which can be preceded by a variable assignment list. See Environment. The first word specifies the name of the command to be executed. Except as specified, the remaining words are passed as arguments to the invoked command. The command name is passed as argument 0 (see exec(2)). The value of a simple-command is its exit status if it terminates normally. If it terminates abnormally due to receipt of a signal, the value is the signal number plus 128. See signal.h(3HEAD) for a list of signal values. Obviously, normal exit status values 129 to 255 cannot be distinguished from abnormal exit caused by receiving signal numbers 1 to 127.
A pipeline is a sequence of one or more commands separated by |. The standard output of each command but the last is connected by a pipe(2) to the standard input of the next command. Each command is run as a separate process; the shell waits for the last command to terminate. The exit status of a pipeline is the exit status of the last command.
A list is a sequence of one or more pipelines separated by ;, &, &&, or ||, and optionally terminated by ;, &, or |&. Of these five symbols, ;, &, and |& have equal precedence, which is lower than that of && and ||. The symbols && and || also have equal precedence. A semicolon (;) causes sequential execution of the preceding pipeline; an ampersand (&) causes asynchronous execution of the preceding pipeline (that is, the shell does not wait for that pipeline to finish). The symbol |& causes asynchronous execution of the preceding command or pipeline with a two-way pipe established to the parent shell.
The standard input and output of the spawned command can be written to and read from by the parent shell using the -p option of the special commands read and print described in Special Commands. The symbol &&(||) causes the list following it to be executed only if the preceding pipeline returns 0 (or a non-zero) value. An arbitrary number of new-lines can appear in a list, instead of a semicolon, to delimit a command.
A command is either a simple-command or one of the following. Unless otherwise stated, the value returned by a command is that of the last simple-command executed in the command.
for identifier [ in word ... ] ; do list ; done
select identifier [ in word ... ] ; do list ; done
case word in [ pattern [ | pattern ] ) list ;; ] ... esac
if list ; then list ; [ elif list ; then list ; ... ] [ else list ; ] fi
while list ; do list ; done
until list ; do list ;
done
(list)
{list}
[[expression]]
function identifier { list ;}
identifier( ) { list ;}
time pipeline
The following reserved words are only recognized as the first word of a command and when not quoted:
! if then else elif fi case esac for while until do done { } function select time [[ ]]
A word beginning with # causes that word and all the following characters up to a new-line to be ignored.
The first word of each command is replaced by the text of an alias if an alias for this word has been defined. An alias name consists of any number of characters excluding metacharacters, quoting characters, file expansion characters, parameter and command substitution characters, and =. The replacement string can contain any valid shell script including the metacharacters listed above. The first word of each command in the replaced text, other than any that are in the process of being replaced, is tested for aliases. If the last character of the alias value is a blank then the word following the alias is also be checked for alias substitution. Aliases can be used to redefine special builtin commands but cannot be used to redefine the reserved words listed above. Aliases can be created, listed, and exported with the alias command and can be removed with the unalias command. Exported aliases remain in effect for scripts invoked by name, but must be reinitialized for separate invocations of the shell. See Invocation. To prevent infinite loops in recursive aliasing, if the shell is not currently processing an alias of the same name, the word is replaced by the value of the alias; otherwise, it is not be replaced.
Aliasing is performed when scripts are read, not while they are executed. Therefore, for an alias to take effect, the alias definition command has to be executed before the command which references the alias is read.
Aliases are frequently used as a short hand for full path names. An option to the aliasing facility allows the value of the alias to be automatically set to the full pathname of the corresponding command. These aliases are called tracked aliases. The value of a tracked alias is defined the first time the corresponding command is looked up and becomes undefined each time the PATH variable is reset. These aliases remain tracked so that the next subsequent reference redefines the value. Several tracked aliases are compiled into the shell. The -h option of the set command makes each referenced command name into a tracked alias.
The following exported aliases are compiled into (and built-in to) the shell but can be unset or redefined:
autoload='typeset -fu' functions='typeset -f' history='fc -l' integer='typeset -i' nohup='nohup ' r='fc -e -'
An example concerning trailing blank characters and reserved words follows. If the user types:
$ alias foo="/bin/ls " $ alias while="/"
the effect of executing:
$ while true > do > echo "Hello, World" > done
is a never-ending sequence of Hello, World strings to the screen. However, if the user types:
$ foo while
the result is an ls listing of /. Since the alias substitution for foo ends in a space character, the next word is checked for alias substitution. The next word, while, has also been aliased, so it is substituted as well. Since it is not in the proper position as a command word, it is not recognized as a reserved word.
If the user types:
$ foo; while
while retains its normal reserved-word properties.
After alias substitution is performed, each word is checked to see if it begins with an unquoted ~. If it does, then the word up to a / is checked to see if it matches a user name. If a match is found, the ~ and the matched login name are replaced by the login directory of the matched user. This is called a tilde substitution. If no match is found, the original text is left unchanged. A ~ by itself, or in front of a /, is replaced by $HOME. A ~ followed by a + or - is replaced by $PWD and $OLDPWD, respectively.
In addition, tilde substitution is attempted when the value of a variable assignment begins with a ~.
A tilde-prefix consists of an unquoted tilde character at the beginning of a word, followed by all of the characters preceding the first unquoted slash in the word, or all the characters in the word if there is no slash. In an assignment, multiple tilde-prefixes can be used: at the beginning of the word (that is, following the equal sign of the assignment), following any unquoted colon or both. A tilde-prefix in an assignment is terminated by the first unquoted colon or slash. If none of the characters in the tilde-prefix are quoted, the characters in the tilde-prefix following the tilde are treated as a possible login name from the user database.
A portable login name cannot contain characters outside the set given in the description of the LOGNAME environment variable. If the login name is null (that is, the tilde-prefix contains only the tilde), the tilde-prefix is replaced by the value of the variable HOME. If HOME is unset, the results are unspecified. Otherwise, the tilde-prefix is replaced by a pathname of the home directory associated with the login name obtained using the getpwnam function. If the system does not recognize the login name, the results are undefined.
Tilde expansion generally occurs only at the beginning of words, but an exception based on historical practice has been included:
PATH=/posix/bin:~dgk/bin
is eligible for tilde expansion because tilde follows a colon and none of the relevant characters is quoted. Consideration was given to prohibiting this behavior because any of the following are reasonable substitutes:
PATH=$(printf %s ~karels/bin : ~bostic/bin) for Dir in ~maart/bin ~srb/bin . do PATH=${PATH:+$PATH:}$Dir done
With the first command, explicit colons are used for each directory. In all cases, the shell performs tilde expansion on each directory because all are separate words to the shell.
Expressions in operands such as:
make -k mumble LIBDIR=~chet/lib
do not qualify as shell variable assignments and tilde expansion is not performed (unless the command does so itself, which make does not).
The special sequence $~ has been designated for future implementations to evaluate as a means of forcing tilde expansion in any word.
Because of the requirement that the word not be quoted, the following are not equivalent; only the last causes tilde expansion:
\~hlj/ ~h\lj/ ~"hlj"/ ~hlj\/ ~hlj/
The results of giving tilde with an unknown login name are undefined because the KornShell ~+ and ~- constructs make use of this condition, but, in general it is an error to give an incorrect login name with tilde. The results of having HOME unset are unspecified because some historical shells treat this as an error.
The standard output from a command enclosed in parenthesis preceded by a dollar sign (that is, $(command)) or a pair of grave accents (``) can be used as part or all of a word. Trailing new-lines are removed. In the second (archaic) form, the string between the quotes is processed for special quoting characters before the command is executed. See Quoting. The command substitution $(cat file) can be replaced by the equivalent but faster $(<file). Command substitution of most special commands that do not perform input/output redirection are carried out without creating a separate process.
Command substitution allows the output of a command to be substituted in place of the command name itself. Command substitution occurs when the command is enclosed as follows:
$(command)
or (backquoted version):
`command`
The shell expands the command substitution by executing command in a subshell environment and replacing the command substitution (the text of command plus the enclosing $() or backquotes) with the standard output of the command, removing sequences of one or more newline characters at the end of the substitution. Embedded newline characters before the end of the output is not be removed; however, they can be treated as field delimiters and eliminated during field splitting, depending on the value of IFS and quoting that is in effect.
Within the backquoted style of command substitution, backslash shall retain its literal meaning, except when followed by:
$ ` \
(dollar-sign, backquote, backslash). The search for the matching backquote is satisfied by the first backquote found without a preceding backslash. During this search, if a non-escaped backquote is encountered within a shell comment, a here-document, an embedded command substitution of the $(command) form, or a quoted string, undefined results occur. A single- or double-quoted string that begins, but does not end, within the `...` sequence produces undefined results.
With the $(command) form, all characters following the open parenthesis to the matching closing parenthesis constitute the command. Any valid shell script can be used for command, except:
The results of command substitution are not field splitting and pathname expansion processed for further tilde expansion, parameter expansion, command substitution or arithmetic expansion. If a command substitution occurs inside double-quotes, it is not be performed on the results of the substitution.
Command substitution can be nested. To specify nesting within the backquoted version, the application must precede the inner backquotes with backslashes; for example:
`\`command\``
The $() form of command substitution solves a problem of inconsistent behavior when using backquotes. For example:
|
Additionally, the backquoted syntax has historical restrictions on the contents of the embedded command. While the new $() form can process any kind of valid embedded script, the backquoted form cannot handle some valid scripts that include backquotes. For example, these otherwise valid embedded scripts do not work in the left column, but do work on the right:
|
Because of these inconsistent behaviors, the backquoted variety of command substitution is not recommended for new applications that nest command substitutions or attempt to embed complex scripts.
If the command substitution consists of a single subshell, such as:
$( (command) )
a portable application must separate the $( and ( into two tokens (that is, separate them with white space). This is required to avoid any ambiguities with arithmetic expansion.
An arithmetic expression enclosed in double parentheses preceded by a dollar sign ( $((arithmetic-expression)) ) is replaced by the value of the arithmetic expression within the double parenthesis. Arithmetic expansion provides a mechanism for evaluating an arithmetic expression and substituting its value. The format for arithmetic expansion is as follows:
$((expression))
The expression is treated as if it were in double-quotes, except that a double-quote inside the expression is not treated specially. The shell expands all tokens in the expression for parameter expansion, command substitution and quote removal.
Next, the shell treats this as an arithmetic expression and substitute the value of the expression. The arithmetic expression is processed according to the rules of the ISO C with the following exceptions:
Command | Result in /bin/ksh | Result in /usr/xpg4/bin/sh |
echo $((010+10)) | 20 | 18 |
echo $((019+10)) | ||
[ 10 ---le $((011)) ] |
As an extension, the shell can recognize arithmetic expressions beyond those listed. If the expression is invalid, the expansion fails and the shell writes a message to standard error indicating the failure.
A simple example using arithmetic expansion:
# repeat a command 100 times x=100 while [ $x -gt 0 ] do command x=$(($x-1)) done
This feature is available in SunOS and only on versions of the UNIX operating system that support the /dev/fd directory for naming open files. Each command argument of the form <(list) or >(list) runs process list asynchronously connected to some file in /dev/fd. The name of this file becomes the argument to the command. If the form with > is selected, then writing on this file provides input for list. If < is used, then the file passed as an argument contains the output of the list process. For example:
paste <(cut -f1 file1) <(cut -f3 file2) | tee >(process1) >(process2)
cuts fields 1 and 3 from the files file1 and file2, respectively, pastes the results together, and sends it to the processes process1 and process2, as well as putting it onto the standard output. The file, which is passed as an argument to the command, is a UNIX pipe(2) so programs that expect to lseek(2) on the file does not work.
A parameter is an identifier, one or more digits, or any of the characters *, @, #, ?, -, $, and !. A variable (a parameter denoted by an identifier) has a value and zero or more attributes. variables can be assigned values and attributes by using the typeset special command. The attributes supported by the shell are described later with the typeset special command. Exported variables pass values and attributes to the environment.
The shell supports a one-dimensional array facility. An element of an array variable is referenced by a subscript. A subscript is denoted by a [, followed by an arithmetic expression, followed by a ]. See Arithmetic Evaluation. To assign values to an array, use set -A name value .... The value of all subscripts must be in the range of 0 through 4095. Arrays need not be declared. Any reference to a variable with a valid subscript is legal and an array is created if necessary. Referencing an array without a subscript is equivalent to referencing the element 0. If an array identifier with subscript * or @ is used, then the value for each of the elements is substituted (separated by a field separator character).
The value of a variable can be assigned by writing:
name=value [ name=value ] ...
If the integer attribute, -i, is set for name, the value is subject to arithmetic evaluation.
Positional parameters, parameters denoted by a number, can be assigned values with the set special command. Parameter $0 is set from argument zero when the shell is invoked. If parameter is one or more digits then it is a positional parameter. A positional parameter of more than one digit must be enclosed in braces.
The format for parameter expansion is as follows:
${expression}
where expression consists of all characters until the matching }. Any } escaped by a backslash or within a quoted string, and characters in embedded arithmetic expansions, command substitutions and variable expansions, are not examined in determining the matching }.
The simplest form for parameter expansion is:
${parameter}
The value, if any, of parameter is substituted.
The parameter name or symbol can be enclosed in braces, which are optional except for positional parameters with more than one digit or when parameter is followed by a character that could be interpreted as part of the name. The matching closing brace are determined by counting brace levels, skipping over enclosed quoted strings and command substitutions.
If the parameter name or symbol is not enclosed in braces, the expansion uses the longest valid name whether or not the symbol represented by that name exists. When the shell is scanning its input to determine the boundaries of a name, it is not bound by its knowledge of what names are already defined. For example, if F is a defined shell variable, the command:
echo $Fred
does not echo the value of $F followed by red; it selects the longest possible valid name, Fred, which in this case might be unset.
If a parameter expansion occurs inside double-quotes:
In addition, a parameter expansion can be modified by using one of the following formats. In each case that a value of word is needed (based on the state of parameter), word is subjected to tilde expansion, parameter expansion, command substitution and arithmetic expansion. If word is not needed, it is not expanded. The } character that delimits the following parameter expansion modifications is determined as described previously in this section and in dquote. (For example, ${foo-bar}xyz} would result in the expansion of foo followed by the string xyz} if foo is set, else the string barxyz}).
${parameter:-word}
${parameter:=word}
${parameter:?[word]}
${parameter:+[word]}
In the parameter expansions shown previously, use of the colon in the format results in a test for a parameter that is unset or null. Omission of the colon results in a test for a parameter that is only unset. The following two tables summarize the effect of the colon:
parameter set and not null | parameter set and null | |
${parameter:-word} | substitute parameter | substitute word |
${parameter-word} | ||
${parameter:=word} | ||
${parameter=word} | ||
${parameter:?word} | ||
${parameter?word} | ||
${parameter:+word} | ||
${parameter+word} |
parameter unset | |
${parameter:-word} | substitute word |
${parameter-word} | |
${parameter:=word} | |
${parameter=word} | |
${parameter:?word} | |
${parameter?word} | |
${parameter:+word} | |
${parameter+word} |
In all cases shown with "substitute", the expression is replaced with the value shown. In all cases shown with "assign", parameter is assigned that value, which also replaces the expression.
${#parameter}
The following four varieties of parameter expansion provide for substring processing. In each case, pattern matching notation (see patmat), rather than regular expression notation, is used to evaluate the patterns. If parameter is * or @, then all the positional parameters, starting with $1, are substituted (separated by a field separator character). Enclosing the full parameter expansion string in double-quotes does not cause the following four varieties of pattern characters to be quoted, whereas quoting characters within the braces has this effect.
${parameter%word}
${parameter%%word}
${parameter#word}
${parameter##word}
Examples:
${parameter:-word}
In this example, ls is executed only if x is null or unset. (The $(ls) command substitution notation is explained in Command Substitution above.)
${x:-$(ls)}
${parameter:=word}
unset X echo ${X:=abc} abc
${parameter:?word}
unset posix echo ${posix:?} sh: posix: parameter null or not set
${parameter:+word}
set a b c echo ${3:+posix} posix
${#parameter}
HOME=/usr/posix echo ${#HOME} 10
${parameter%word}
x=file.c echo ${x%.c}.o file.o
${parameter%%word}
x=posix/src/std echo ${x%%/*} posix
${parameter#word}
x=$HOME/src/cmd echo ${x#$HOME} /src/cmd
${parameter##word}
x=/one/two/three echo ${x##*/} three
The following parameters are automatically set by the shell:
#
-
?
$
_
!
ERRNO
LINENO
OLDPWD
OPTARG
OPTIND
PPID
PWD
RANDOM
REPLY
SECONDS
The following variables are used by the shell:
CDPATH
COLUMNS
EDITOR
ENV
This variable can be used to set aliases and other items local to the invocation of a shell. The file referred to by ENV differs from $HOME/.profile in that .profile is typically executed at session startup, whereas the ENV file is executed at the beginning of each shell invocation. The ENV value is interpreted in a manner similar to a dot script, in that the commands are executed in the current environment and the file needs to be readable, but not executable. However, unlike dot scripts, no PATH searching is performed. This is used as a guard against Trojan Horse security breaches.
FCEDIT
FPATH
HISTFILE
HISTSIZE
HOME
IFS
LANG
LC_ALL
LC_COLLATE
LC_CTYPE
LC_MESSAGES
LINENO
LINES
MAILCHECK
MAILPATH
NLSPATH
PATH
PPID
PS1
PS2
PS3
PS4
PWD
SHELL
TMOUT
VISUAL
The shell gives default values to PATH, PS1, PS2, PS3, PS4, MAILCHECK, FCEDIT, TMOUT, and IFS, while HOME, SHELL, ENV, and MAIL are not set at all by the shell (although HOME is set by login(1)). On some systems MAIL and SHELL are also set by login.
After parameter and command substitution, the results of substitutions are scanned for the field separator characters (those found in IFS) and split into distinct arguments where such characters are found. Explicit null arguments ( "" ) or ('') are retained. Implicit null arguments (those resulting from parameters that have no values) are removed.
Following substitution, each command word is scanned for the characters *, ?, and [ unless the -f option has been set. If one of these characters appears, the word is regarded as a pattern. The word is replaced with lexicographically sorted file names that match the pattern. If no file name is found that matches the pattern, the word is left unchanged. When a pattern is used for file name generation, the character period (.) at the start of a file name or immediately following a /, as well as the character / itself, must be matched explicitly. A file name beginning with a period is not matched with a pattern with the period inside parentheses. That is, ls .@(r*) would locate a file named .restore, but ls @(.r*) would not. In other instances of pattern matching, the / and . are not treated specially.
*
?
[...]
A pattern-list is a list of one or more patterns separated from each other with a |. Composite patterns can be formed with one or more of the following:
?(pattern-list)
*(pattern-list)
+(pattern-list)
@(pattern-list)
!(pattern-list)
Each of the metacharacters listed above (see Definitions) has a special meaning to the shell and causes termination of a word unless quoted. A character can be quoted (that is, made to stand for itself) by preceding it with a \. The pair \NEWLINE is removed. All characters enclosed between a pair of single quote marks (' ') are quoted. A single quote cannot appear within single quotes. Inside double quote marks (""), parameter and command substitution occur and \ quotes the characters \, `, ", and $. The meaning of $* and $@ is identical when not quoted or when used as a parameter assignment value or as a file name. However, when used as a command argument, $* is equivalent to ``$1d$2d...'', where d is the first character of the IFS variable, whereas $@ is equivalent to $1 $2 .... Inside grave quote marks (``), \ quotes the characters \, ', and $. If the grave quotes occur within double quotes, then \ also quotes the character ".
The special meaning of reserved words or aliases can be removed by quoting any character of the reserved word. The recognition of function names or special command names listed cannot be altered by quoting them.
An ability to perform integer arithmetic is provided with the special command let. Evaluations are performed using long arithmetic. Constants are of the form [ base# ] n where base is a decimal number between two and thirty-six representing the arithmetic base and n is a number in that base. If base is omitted then base 10 is used.
An arithmetic expression uses the same syntax, precedence, and associativity of expression as the C language. All the integral operators, other than ++, -;, ?:, and , are supported. Variables can be referenced by name within an arithmetic expression without using the parameter substitution syntax. When a variable is referenced, its value is evaluated as an arithmetic expression.
An internal integer representation of a variable can be specified with the -i option of the typeset special command. Arithmetic evaluation is performed on the value of each assignment to a variable with the -i attribute. If you do not specify an arithmetic base, the first assignment to the variable determines the arithmetic base. This base is used when parameter substitution occurs.
Since many of the arithmetic operators require quoting, an alternative form of the let command is provided. For any command which begins with a ((, all the characters until a matching )) are treated as a quoted expression. More precisely, ((...)) is equivalent to let "...".
When used interactively, the shell prompts with the parameter expanded value of PS1 before reading a command. If at any time a new-line is typed and further input is needed to complete a command, then the secondary prompt (that is, the value of PS2) is issued.
A conditional expression is used with the [[ compound command to test attributes of files and to compare strings. Word splitting and file name generation are not performed on the words between [[ and ]]. Each expression can be constructed from one or more of the following unary or binary expressions:
-a file
-b file
-c file
-d file
-e file
-f file
-g file
-h file
-k file
-n string
-o option
-p file
-r file
-s file
-t fildes
-u file
-w file
-x file
-z string
-L file
-O file
-G file
-S file
file1 -nt file2
file1 -ot file2
file1 -ef file2
string
string = pattern
string != pattern
string1 < string2
string1 > string2
exp1 -eq exp2
exp1 -ne exp2
exp1 -lt exp2
exp1 -gt exp2
exp1 -le exp2
exp1 -ge exp2
In each of the above expressions, if file is of the form /dev/fd/n, where n is an integer, then the test is applied to the open file whose descriptor number is n.
A compound expression can be constructed from these primitives by using any of the following, listed in decreasing order of precedence.
(expression)
! expression
expression1 && expression2
expression1 || expression2
Before a command is executed, its input and output can be redirected using a special notation interpreted by the shell. The following can appear anywhere in a simple-command or can precede or follow a command and are not passed on to the invoked command. Command and parameter substitution occur before word or digit is used except as noted. File name generation occurs only if the pattern matches a single file, and blank interpretation is not performed.
<word
>word
>|word
>>word
<>word
<< [-]word
<&digit
<&-
<&p
>&p
If one of the above is preceded by a digit, then the file descriptor number referred to is that specified by the digit (instead of the default 0 or 1). For example:
... 2>&1
means file descriptor 2 is to be opened for writing as a duplicate of file descriptor 1.
The order in which redirections are specified is significant. The shell evaluates each redirection in terms of the (file descriptor, file) association at the time of evaluation. For example:
... 1>fname 2>&1
first associates file descriptor 1 with file fname. It then associates file descriptor 2 with the file associated with file descriptor 1 (that is, fname). If the order of redirections were reversed, file descriptor 2 would be associated with the terminal (assuming file descriptor 1 had been) and then file descriptor 1 would be associated with file fname.
If a command is followed by & and job control is not active, then the default standard input for the command is the empty file /dev/null. Otherwise, the environment for the execution of a command contains the file descriptors of the invoking shell as modified by input/output specifications.
The environment (see environ(5)) is a list of name-value pairs that is passed to an executed program in the same way as a normal argument list. The names must be identifiers and the values are character strings. The shell interacts with the environment in several ways. On invocation, the shell scans the environment and creates a variable for each name found, giving it the corresponding value and marking it export. Executed commands inherit the environment. If the user modifies the values of these variables or creates new ones, using the export or typeset -x commands, they become part of the environment. The environment seen by any executed command is thus composed of any name-value pairs originally inherited by the shell, whose values can be modified by the current shell, plus any additions which must be noted in export or typeset -x commands.
The environment for any simple-command or function can be augmented by prefixing it with one or more variable assignments. A variable assignment argument is a word of the form identifier=value. Thus:
TERM=450 cmd args
and
(export TERM; TERM=450; cmd args)
are equivalent (as far as the above execution of cmd is concerned, except for special commands listed that are preceded with an asterisk).
If the -k flag is set, all variable assignment arguments are placed in the environment, even if they occur after the command name. The following first prints a=b c and then c:
echo a=b c set -k echo a=b c
This feature is intended for use with scripts written for early versions of the shell and its use in new scripts is strongly discouraged. It is likely to disappear someday.
The function reserved word, described in the Commands section above, is used to define shell functions. Shell functions are read in and stored internally. Alias names are resolved when the function is read. Functions are executed like commands with the arguments passed as positional parameters. See Execution.
Functions execute in the same process as the caller and share all files and present working directory with the caller. Traps caught by the caller are reset to their default action inside the function. A trap condition that is not caught or ignored by the function causes the function to terminate and the condition to be passed on to the caller.
A trap on EXIT set inside a function is executed after the function completes in the environment of the caller. This is true only for non-POSIX-style functions, that is, functions declared as
function func
as opposed to POSIX-style functions, declared as
func()
Ordinarily, variables are shared between the calling program and the function. However, the typeset special command used within a function defines local variables whose scope includes the current function and all functions it calls.
The special command return is used to return from function calls. Errors within functions return control to the caller.
The names of all functions can be listed with typeset-f. typeset -f lists all function names as well as the text of all functions. typeset -f function-names lists the text of the named functions only. Functions can be undefined with the -f option of the unset special command.
Ordinarily, functions are unset when the shell executes a shell script. The -xf option of the typeset command allows a function to be exported to scripts that are executed without a separate invocation of the shell. Functions that need to be defined across separate invocations of the shell should be specified in the ENV file with the -xf option of typeset.
A function is a user-defined name that is used as a simple command to call a compound command with new positional parameters. A function is defined with a function definition command.
The format of a function definition command is as follows:
fname() compound-command[io-redirect ...]
The function is named fname; it must be a name. An implementation can allow other characters in a function name as an extension. The implementation maintains separate name spaces for functions and variables.
The () in the function definition command consists of two operators. Therefore, intermixing blank characters with the fname, (, and ) is allowed, but unnecessary.
The argument compound-command represents a compound command.
When the function is declared, none of the expansions in wordexp is performed on the text in compound-command or io-redirect; all expansions is performed as normal each time the function is called. Similarly, the optional io-redirect redirections and any variable assignments within compound-command is performed during the execution of the function itself, not the function definition.
When a function is executed, it has the syntax-error and variable-assignment properties described for the special built-in utilities.
The compound-command is executed whenever the function name is specified as the name of a simple command The operands to the command temporarily becomes the positional parameters during the execution of the compound-command; the special parameter # is also changed to reflect the number of operands. The special parameter 0 is unchanged. When the function completes, the values of the positional parameters and the special parameter # is restored to the values they had before the function was executed. If the special built-in return is executed in the compound-command, the function completes and execution resumes with the next command after the function call.
An example of how a function definition can be used wherever a simple command is allowed:
# If variable i is equal to "yes", # define function foo to be ls -l # [ "$i" = yes ] && foo() { ls -l }
The exit status of a function definition is 0 if the function was declared successfully; otherwise, it is greater than zero. The exit status of a function invocation is the exit status of the last command executed by the function.
If the monitor option of the set command is turned on, an interactive shell associates a job with each pipeline. It keeps a table of current jobs, printed by the jobs command, and assigns them small integer numbers. When a job is started asynchronously with &, the shell prints a line which looks like:
[1] 1234
indicating that the job, which was started asynchronously, was job number 1 and had one (top-level) process, whose process id was 1234.
If you are running a job and wish to do something else you can press the key ^Z (Control-Z) which sends a STOP signal to the current job. The shell normally indicates that the job has been `Stopped', and print another prompt. You can then manipulate the state of this job, putting it in the background with the bg command, or run some other commands and then eventually bring the job back into the foreground with the foreground command fg. A ^Z takes effect immediately and is like an interrupt in that pending output and unread input are discarded when it is typed.
A job being run in the background stops if it tries to read from the terminal. Background jobs are normally allowed to produce output, but this can be disabled by giving the command "stty tostop". If you set this tty option, then background jobs stop when they try to produce output as they do when they try to read input.
There are several ways to refer to jobs in the shell. A job can be referred to by the process id of any process of the job or by one of the following:
%number
%string
%?string
%%
%+
%-
The shell learns immediately whenever a process changes state. It normally informs you whenever a job becomes blocked so that no further progress is possible, but only just before it prints a prompt. This is done so that it does not otherwise disturb your work.
When the monitor mode is on, each background job that completes triggers any trap set for CHLD.
When you try to leave the shell while jobs are running or stopped, you are warned with the message, `You have stopped(running) jobs.' You can use the jobs command to see what they are. If you do this or immediately try to exit again, the shell does not warn you a second time, and the stopped jobs is terminated. If you have jobs running for which the nohup command was invoked and attempt to logout, you are warned with the message:
You have jobs running.
You need to logout a second time to actually logout. However, your background jobs continue to run.
The INT and QUIT signals for an invoked command are ignored if the command is followed by & and the -monitor option is not active. Otherwise, signals have the values inherited by the shell from its parent. See the trap special command section.
Each time a command is executed, the above substitutions are carried out. If the command name matches one of the Special Commands listed, it is executed within the current shell process. Next, the command name is checked to see if it matches one of the user defined functions. If it does, the positional parameters are saved and then reset to the arguments of the function call. When the function completes or issues a return, the positional parameter list is restored and any trap set on EXIT within the function is executed. The value of a function is the value of the last command executed. A function is also executed in the current shell process. If a command name is not a special command or a user defined function, a process is created and an attempt is made to execute the command using exec(2).
The shell variable PATH defines the search path for the directory containing the command. Alternative directory names are separated by a colon (:). The default path is /bin:/usr/bin: (specifying /bin, /usr/bin, and the current directory in that order). The current directory can be specified by two or more adjacent colons, or by a colon at the beginning or end of the path list. If the command name contains a / then the search path is not used. Otherwise, each directory in the path is searched for an executable file. If the file has execute permission but is not a directory or an a.out file, it is assumed to be a file containing shell commands. A sub-shell is spawned to read it. All non-exported aliases, functions, and variables are removed in this case. A parenthesized command is executed in a sub-shell without removing non-exported quantities.
The text of the last HISTSIZE (default 128) commands entered from a terminal device is saved in a history file. The file $HOME/.sh_history is used if the HISTFILE variable is not set or if the file it names is not writable. A shell can access the commands of all interactive shells which use the same named HISTFILE. The special command fc is used to list or edit a portion of this file. The portion of the file to be edited or listed can be selected by number or by giving the first character or characters of the command. A single command or range of commands can be specified. If you do not specify an editor program as an argument to fc then the value of the variable FCEDIT is used. If FCEDIT is not defined, then /bin/ed is used. The edited command(s) is printed and re-executed upon leaving the editor. The editor name - is used to skip the editing phase and to re-execute the command. In this case a substitution parameter of the form old=new can be used to modify the command before execution. For example, if r is aliased to 'fc -e -' then typing 'r bad=good c' re-executes the most recent command which starts with the letter c, replacing the first occurrence of the string bad with the string good.
Normally, each command line entered from a terminal device is simply typed followed by a new-line (RETURN or LINEFEED). If either the emacs, gmacs, or vi option is active, the user can edit the command line. To be in either of these edit modes set the corresponding option. An editing option is automatically selected each time the VISUAL or EDITOR variable is assigned a value ending in either of these option names.
The editing features require that the user's terminal accept RETURN as carriage return without line feed and that a space must overwrite the current character on the screen.
The editing modes implement a concept where the user is looking through a window at the current line. The window width is the value of COLUMNS if it is defined, otherwise 80. If the window width is too small to display the prompt and leave at least 8 columns to enter input, the prompt is truncated from the left. If the line is longer than the window width minus two, a mark is displayed at the end of the window to notify the user. As the cursor moves and reaches the window boundaries the window are centered about the cursor. The mark is a > if the line extends on the right side of the window, < if the line extends on the left, and * if the line extends on both sides of the window.
The search commands in each edit mode provide access to the history file. Only strings are matched, not patterns, although a leading caret (^) in the string restricts the match to begin at the first character in the line.
This mode is entered by enabling either the emacs or gmacs option. The only difference between these two modes is the way they handle ^T. To edit, move the cursor to the point needing correction and then insert or delete characters or words as needed. All the editing commands are control characters or escape sequences. The notation for control characters is caret ( ^ ) followed by the character. For example, ^F is the notation for control F. This is entered by depressing `f' while holding down the CTRL (control) key. The SHIFT key is not depressed. (The notation ^? indicates the DEL (delete) key.)
The notation for escape sequences is M- followed by a character. For example, M-f (pronounced Meta f) is entered by depressing ESC (ascii 033) followed by `f'. (M-F would be the notation for ESC followed by SHIFT (capital) `F'.)
All edit commands operate from any place on the line (not just at the beginning). Neither the RETURN nor the LINEFEED key is entered after edit commands except when noted.
^F
M-f
^B
M-b
^A
^E
^]char
M-^]char
^X^X
erase
^D
M-d
M-^H
M-h
M-^?
^T
^C
M-c
M-l
^K
^W
M-p
kill
^Y
^L
^@
M-space
J
M
eof
^P
M-<
M->
^N
^Rstring
^O
M-digits
M-letter
M-[letter
M-.
M-_
M-*
M-ESC
M-=
^U
\
^V
M-#
There are two typing modes. Initially, when you enter a command you are in the input mode. To edit, enter control mode by typing ESC (033) and move the cursor to the point needing correction and then insert or delete characters or words as needed. Most control commands accept an optional repeat count prior to the command.
When in vi mode on most systems, canonical processing is initially enabled and the command is echoed again if the speed is 1200 baud or greater and it contains any control characters or less than one second has elapsed since the prompt was printed. The ESC character terminates canonical processing for the remainder of the command and the user can then modify the command line. This scheme has the advantages of canonical processing with the type-ahead echoing of raw mode.
If the option viraw is also set, the terminal always have canonical processing disabled. This mode is implicit for systems that do not support two alternate end of line delimiters, and can be helpful for certain terminals.
By default the editor is in input mode.
erase
^W
^D
^V
\
The following commands move the cursor:
[count]l
[count]w
[count]W
[count]e
[count]E
[count]h
[count]b
[count]B
[count]|
[count]fc
[count]Fc
[count]tc
[count]Tc
[count];
[count],
0
^
$
%
These commands access your command history.
[count]k
[count]-
[count]j
[count]+
[count]G
/string
?string
n
N
These commands modifies the line.
a
A
[count]cmotion
c[count]motion
C
[count]s
S
D
[count]dmotion
d[count]motion
i
I
[count]P
[count]p
R
[count]rc
[count]x
[count]X
[count].
[count]~
[count]_
*
\
Miscellaneous commands.
[count]ymotion
y[count]motion
Y
u
U
[count]v
^L
J
M
#
=
@letter
The following simple-commands are executed in the shell process. Input/Output redirection is permitted. Unless otherwise indicated, the output is written on file descriptor 1 and the exit status, when there is no syntax error, is 0. Commands that are preceded by one or two * (asterisks) are treated specially in the following ways:
* : [ arg ... ]
* . file [ arg ... ]
** alias [ -tx ] [ name[ =value ] ] ...
bg [ %job... ]
* break [ n ]
* continue [ n ]
cd [ -L ] [ -P ] [ arg ]
cd old new
-L
-P
If both -L and -P options are specified, the last option to be invoked is used and the other is ignored. If neither -L nor -P is specified, the operand is handled dot-dot logically.
The second form of cd substitutes the string new for the string old in the current directory name, PWD, and tries to change to this new directory. The cd command cannot be executed by rksh.
command [-p] [command_name] [argument ...]
command [-v | -V] command_name
echo [ arg ... ]
* eval [ arg ... ]
* exec [ arg ... ]
* exit [ n ]
** export [ name[=value] ] ...
** export -p
When -p is specified, export writes to the standard output the names and values of all exported variables in the following format:
"export %s=%s\n", name, value
if name is set, and:
"export %s\n", name
if name is unset.
The shell formats the output, including the proper use of quoting, so that it is suitable for reinput to the shell as commands that achieve the same exporting results, except for the following:
fc [ -e ename ] [ -nlr ] [ first [ last ] ]
fc -e - [ old=new ] [ command ]
fc -s [ old=new ] [ command ]
fg [ %job... ]
getopts optstring name [ arg ... ]
getopts places the next option letter it finds inside variable name each time it is invoked with a + prepended when arg begins with a +. The index of the next arg is stored in OPTIND. The option argument, if any, gets stored in OPTARG.
A leading : in optstring causes getopts to store the letter of an invalid option in OPTARG, and to set name to ? for an unknown option and to : when a required option is missing. Otherwise, getopts prints an error message. The exit status is non-zero when there are no more options. See getoptcvt(1) for usage and description.
getopts supports both traditional single-character short options and long options defined by Sun's Command Line Interface Paradigm (CLIP).
Each long option is an alias for a short option and is specified in parentheses following its equivalent short option. For example, you can specify the long option file as an alias for the short option f using the following script line:
getopts "f(file)" opt
Precede long options on the command line with -- or ++. In the example above, --file on the command line would be the equivalent of -f, and ++file on the command line would be the equivalent of +f.
Each short option can have multiple long option equivalents, although this is in violation of the CLIP specification and should be used with caution. You must enclose each long option equivalent parentheses, as follows:
getopts "f:(file)(input-file)o:(output-file)"
In the above example, both --file and --input-file are the equivalent of -f, and --output-file is the equivalent of -o.
The variable name is always set to a short option. When a long option is specified on the command line, name is set to the short-option equivalent.
hash [ name ... ]
hash [ -r ]
jobs [ -lnp ] [ %job ... ]
kill [ -sig ] %job ...
kill [ -sig ] pid ...
kill -l
let arg...
The exit status is 0 if the value of the last expression is non-zero, and 1 otherwise.
login argument ...
* newgrp [ arg ... ]
print [ -Rnprsu[n ] ] [ arg ... ]
-n
-R | -r
-p
-s
-u [ n ]
pwd [ -L | -P ]
-L
-P
If both -L and -P are specified, the last one applies. If neither -L nor -P is specified, pwd behaves as if -L had been specified.
read [ -prsu[ n ] ] [ name?prompt ] [ name ... ]
** readonly [ name[=value] ] ...
** readonly -p
When -p is specified, readonly writes to the standard output the names and values of all read-only variables, in the following format:
"readonly %s=%s\n", name, value
if name is set, and:
"readonly $s\n", name
if name is unset.
The shell formats the output, including the proper use of quoting, so that it is suitable for reinput to the shell as commands that achieve the same value and readonly attribute-setting results in a shell execution environment in which:
* return [ n ]
set [ ±abCefhkmnopstuvx ] [ ±o option ]... [ ±A name ] [ arg ... ]
-A
-a
-b
"[%d]%c %s%s\n", <job-number>, <current>, <status>, \ whe<job-name>
where the fields are as follows:
<current>
<job-number>
<status>
<job-name>
When the shell notifies the user a job has been completed, it can remove the job's process ID from the list of those known in the current shell execution environment. Asynchronous notification is not enabled by default.
-C
-e
-f
-h
-k
-m
-n
-o
-o
allexport
errexit
bgnice
emacs
gmacs
ignoreeof
keyword
markdirs
monitor
noclobber
noexec
noglob
nolog
notify
nounset
privileged
verbose
trackall
vi
viraw
xtrace
If no option name is supplied, the current option settings are printed.
-p
-s
-t
-u
-v
-x
-
--
Using + rather than - causes these flags to be turned off. These flags can also be used upon invocation of the shell. The current set of flags can be found in $-. Unless -A is specified, the remaining arguments are positional parameters and are assigned, in order, to $1 $2 .... If no arguments are given, the names and values of all variables are printed on the standard output.
* shift [ n ]
stop%jobid ...
stop pid ...
suspend
test expression
* times
* trap [ arg sig ... ]
If arg is -, the shell resets each sig to the default value. If arg is null (''), the shell ignores each specified sig if it arises. Otherwise, arg is read and executed by the shell when one of the corresponding sigs arises. The action of the trap overrides a previous action (either default action or one explicitly set). The value of $? after the trap action completes is the value it had before the trap was invoked.
sig can be EXIT, 0 (equivalent to EXIT) or a signal specified using a symbolic name, without the SIG prefix, for example, HUP, INT, QUIT, TERM. If sig is 0 or EXIT and the trap statement is executed inside the body of a function, then the command arg is executed after the function completes. If sig is 0 or EXIT for a trap set outside any function, the command arg is executed on exit from the shell. If sig is ERR, arg is executed whenever a command has a non-zero exit status. If sig is DEBUG, arg is executed after each command.
The environment in which the shell executes a trap on EXIT is identical to the environment immediately after the last command executed before the trap on EXIT was taken.
Each time the trap is invoked, arg is processed in a manner equivalent to eval "$arg".
Signals that were ignored on entry to a non-interactive shell cannot be trapped or reset, although no error need be reported when attempting to do so. An interactive shell can reset or catch signals ignored on entry. Traps remain in place for a given shell until explicitly changed with another trap command.
When a subshell is entered, traps are set to the default args. This does not imply that the trap command cannot be used within the subshell to set new traps.
The trap command with no arguments writes to standard output a list of commands associated with each sig. The format is:
trap -- %s %s ... <arg>, <sig> ...
The shell formats the output, including the proper use of quoting, so that it is suitable for reinput to the shell as commands that achieve the same trapping results. For example:
save_traps=$(trap) ... eval "$save_traps"
If the trap name or number is invalid, a non-zero exit status is returned. Otherwise, 0 is returned. For both interactive and non-interactive shells, invalid signal names or numbers are not considered a syntax error and dol not cause the shell to abort.
Traps are not processed while a job is waiting for a foreground process. Thus, a trap on CHLD won't be executed until the foreground job terminates.
type name ...
** typeset [ ±HLRZfilrtux[n] ] [ name[=value ] ] ...
-H
-L
-R
-Z
-f
-i
-l
-r
-t
-u
-x
The -i attribute cannot be specified along with -R, -L, -Z, or -f.
Using + rather than - causes these flags to be turned off. If no name arguments are given but flags are specified, a list of names (and optionally the values) of the variables which have these flags set is printed. (Using + rather than - keeps the values from being printed.) If no names and flags are given, the names and attributes of all variables are printed.
ulimit [ -HSacdfnstv ] [ limit ]
-a
-c
-d
-f
-n
-s
-t
-v
If no option is given, -f is assumed.
umask [-S] [ mask ]
unalias name ...
unalias -a
unset [ -f ] name ...
* wait [ job ]
whence [ -pv ] name ...
The -v flag produces a more verbose report.
The -p flag does a path search for name even if name is an alias, a function, or a reserved word.
If the shell is invoked by exec(2), and the first character of argument zero ($0) is -, then the shell is assumed to be a login shell and commands are read from /etc/profile and then from either .profile in the current directory or $HOME/.profile, if either file exists. Next, commands are read from the file named by performing parameter substitution on the value of the environment variable ENV if the file exists. If the -s flag is not present and arg is, then a path search is performed on the first arg to determine the name of the script to execute. The script arg must have read permission and any setuid and setgid settings are ignored. If the script is not found on the path, arg is processed as if it named a builtin command or function. Commands are then read as described as follows. The following flags are interpreted by the shell when it is invoked:
-c
-s
-i
-r
The remaining flags and arguments are described under the set command above.
rksh is used to set up login names and execution environments whose capabilities are more controlled than those of the standard shell. The actions of rksh are identical to those of ksh, except that the following are disallowed:
The restrictions above are enforced after .profile and the ENV files are interpreted.
When a command to be executed is found to be a shell procedure, rksh invokes ksh to execute it. Thus, it is possible to provide to the end-user shell procedures that have access to the full power of the standard shell, while imposing a limited menu of commands; this scheme assumes that the end-user does not have write and execute permissions in the same directory.
The net effect of these rules is that the writer of the .profile has complete control over user actions, by performing guaranteed setup actions and leaving the user in an appropriate directory (probably not the login directory).
The system administrator often sets up a directory of commands (that is, /usr/rbin) that can be safely invoked by rksh.
Errors detected by the shell, such as syntax errors, cause the shell to return a non-zero exit status. Otherwise, the shell returns the exit status of the last command executed (see also the exit command above). If the shell is being used non-interactively then execution of the shell file is abandoned. Run time errors detected by the shell are reported by printing the command or function name and the error condition. If the line number that the error occurred on is greater than one, then the line number is also printed in square brackets ([]) after the command or function name.
For a non-interactive shell, an error condition encountered by a special built-in or other type of utility causes the shell to write a diagnostic message to standard error and exit as shown in the following table:
|
An expansion error is one that occurs when the shell expansions are carried out (for example, ${x!y}, because ! is not a valid operator). An implementation can treat these as syntax errors if it is able to detect them during tokenization, rather than during expansion.
If any of the errors shown as "might exit" or "exits" occur in a subshell, the subshell exits or might exit with a non-zero status, but the script containing the subshell does not exit because of the error.
In all of the cases shown in the table, an interactive shell writes a diagnostic message to standard error without exiting.
See largefile(5) for the description of the behavior of ksh and rksh when encountering files greater than or equal to 2 Gbyte (2^31 bytes).
Each command has an exit status that can influence the behavior of other shell commands. The exit status of commands that are not utilities is documented in this section. The exit status of the standard utilities is documented in their respective sections.
If a command is not found, the exit status is 127. If the command name is found, but it is not an executable utility, the exit status is 126. Applications that invoke utilities without using the shell should use these exit status values to report similar errors.
If a command fails during word expansion or redirection, its exit status is greater than zero.
When reporting the exit status with the special parameter ?, the shell reports the full eight bits of exit status available. The exit status of a command that terminated because it received a signal reported as greater than 128.
/etc/profile
/etc/suid_profile
$HOME/.profile
/tmp/sh*
See attributes(5) for descriptions of the following attributes:
|
|
cat(1), cd(1), chmod(1), cut(1), echo(1), env(1), getoptcvt(1), jobs(1), login(1), newgrp(1), paste(1), pfksh(1), pfexec(1), ps(1), shell_builtins(1), stty(1), test(1), vi(1), dup(2), exec(2), fork(2), ioctl(2), lseek(2), pipe(2), ulimit(2), umask(2), rand(3C), signal(3C), signal.h(3HEAD), wait(3C), a.out(4), profile(4), attributes(5), environ(5), largefile(5), standards(5)
Morris I. Bolsky and David G. Korn, The KornShell Command and Programming Language, Prentice Hall, 1989.
The use of setuid shell scripts is strongly discouraged.
If a command which is a tracked alias is executed, and then a command with the same name is installed in a directory in the search path before the directory where the original command was found, the shell continues to exec the original command. Use the -t option of the alias command to correct this situation.
Some very old shell scripts contain a ^ as a synonym for the pipe character |.
Using the fc built-in command within a compound command causes the whole command to disappear from the history file.
The built-in command .file reads the whole file before any commands are executed. Therefore, alias and unalias commands in the file does not apply to any functions defined in the file.
When the shell executes a shell script that attempts to execute a non-existent command interpreter, the shell returns an erroneous diagnostic message that the shell script file does not exist.
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |