NAME

Ksh Summary - basic reference for the Korn Shell


VERSION

Version: 0.91

Last Modified: Mon Feb 18 00:22:03 EST 2013

Contact: sales@eeconsulting.net


COPYRIGHT

The information contained herein is copyright (c) 1998-2013 by Frank J. Edwards of Edwards & Edwards Consulting. License is granted for personal use only. Within a company environment, individuals may use this information for their consumption only; presenting this summary without this copyright notice and contact information remaining intact is a violation of the copyright.


DESCRIPTION

In the following descriptions, the filename may be replaced with the value of a variable, if desired, as long as the rules in the VARIABLES section are followed.

I/O REDIRECTIONS

The redirection mechanisms can be applied to complex shell commands as a whole if the shell commands are placed within parentheses, such as:

    date > file
    ls -l >> file
    who >> file

is the same as

    ( date; ls -l; who ) > file

which runs the commands in a subshell (causes the current shell to fork and execute a subshell), and

    { date; ls -l; who; } > file

which runs the commands within the current shell (no fork occurs). Note the required semicolon just before the close brace.

<file

Read input from the given file instead of from the keyboard, i.e. redirect stdin from file.

>file

Write output to the given file instead of to the screen, i.e. redirect stdout to file.

2>file

Write errors to the given file instead of to the screen, i.e. redirect stderr to file.

2>&1

Send stderr to the same place that stdout is going. This copies the file descriptor from stdout to stderr instead of open()'ing stderr again so the two data streams share the same buffer instead of each having its own buffer. (Technically, they share the same file descriptor. And because each file descriptor has it's own lseek field in the kernel's file table, this prevents output to one file descriptor from overwriting the other.)

QUOTING

Double Quotes

The "D" in "Double quotes" stands for DO dollar signs, ie. do variable substitution -- but prevent any other interpretation, such as I/O redirection, wildcards, etc.

Single Quotes

The "S" in "Single quote" stands for SUPPRESS dollar signs, ie. prevent any interpretation of the contents. No substitutions, no wildcards, no IO redirection, or anything else.

The backslash toggles the meaning of the next character. So if the next character was special (such as the * as a wildcard or | as a pipe) the backslash turns that off, and if the next character as not special (such as the letter n in echo) the backslash turns it on.

VARIABLES

Variables are used to contain values that may change during the execution of the shell. Typically, these are filenames, data read from the keyboard or a data file, calculated values, or similar.

Variable names consist of any sequence of letters, digits, and underscores, as long as they start with a non-digit. There is no (practical) limit to the length of a variable name. In advanced shell scripts, variables called compound variables have names that can contain periods as well.

The value of a variable may contain spaces, tabs, or other characters considered to be delimiters by the shell, so any time you want to use the value of a variable you should place double quotes around it. Remember the general rule: always put double quotes around dollar signs. Only break this rule when you want the formatting content to be removed (which is, frankly, pretty rare).

Modifiers

It's our recommendation to avoid these. Code that uses if-then-else-fi statements will be much more readable by others. And it's impossible to Google for these as they are entirely punctuation and Google won't allow a search that is completely punctuation.

The result of variable substitution can be modified before being used if the variable name is enclosed within braces ({ and }) and the appropriate modifier characters are used:

${var-string}

Use the value of var unless it's empty; then use string.

${var=string}

Use the value of var unless it's empty; then assign string to var and use it.

${var?string}

Use the value of var unless it's empty; then print string as an error message and terminate the shell.

${var+string}

Use the value of var unless it's NOT empty; then use string.

${var#wildpat}

Use the value of var after removing any characters from the front of the value which match the wildcard pattern wildpat. The characters matched by the pattern are the shortest possible string.

${var##wildpat}

Same as above, but the match is the longest possible string.

${var%wildpat}

Same as #, but this one trims from the end of the string instead of the beginning. It matches the shortest possible string.

${var%%wildpat}

Same as above, but the match is the longest possible string.

${var:start:len}

Use a portion of the content as described by the starting character and the number of characters. If the variable name is an array reference, such as array[@], then the start and len fields are subscript references instead of character references. Only in ksh93.

${var/wildpat/replacement}

Replace the first part of the content that matches wildpat with the replacement string. The pattern may start with # to anchor it at the beginning of the content and % to anchor it at the end. Only in ksh93.

${var//wildpat/replacement}

Replace the all parts of the content that match wildpat with the replacement string. The pattern may start with # to anchor it at the beginning of the content and % to anchor it at the end. Only in ksh93.

$$

The process id of the shell. This is usually used for temporary filenames, such as /tmp/somebase.$$.

$!

The process id of the last job to be executed in the background.

$0

Name of the shell script that is running. It may include a pathname, so it would be more appropriate to use basename, or a similar construct, to remove the directory component before using it in an output statement.

    prog=$(basename $0)
    USAGE="Usage:  $prog fromfile tofile ..."

or the more efficient form,

    prog=${0##*/}
    USAGE="Usage:  $prog fromfile tofile ..."
$1-$n

These represent the command line parameters provided by the user of the script when it was executed. Braces are needed around the numeric portion if the value is more than a single digit.

$#

The number of command line parameters.

"$@"

The values of the command line parameters with double quotes around individual parameters.

The last three variables, $n, $#, and $@, are specific shortcuts of the general technique of accessing elements of an array:

"${array[n]}"

This accesses the nth element of array.

"${array[@]}"

This accesses all of the elements of array, quoted as described above under $@.

${#array[@]}

This provides the number of elements in array.

Always put double quotes around variable values. Such as:

    if [[ -f "$dir/$1" -o -d "$dir/$1" ]]

This rules prevents the shell from interpreting any formatting that might appear within the value of a variable (obviously, if a variable cannot contain spaces, tabs, or newlines, then you needn't use double quotes -- an example would be $$ or $#). It also prevents errors when a variable is empty and the value is used in a location where a value is required. This is common inside [[ and ]] and when changing the command line parameter list via set --. [Note: there are certain locations where the shell does not perform word breaking, such as inside [[ and ]] and so the double quotes around variables are not necessary. However, it's a good habit to get into because the list of places where they are NOT necessary is rather short!]

Always use (( and )) for numeric tests. Such as:

    typeset -i count=0
    if (( count < high ))
    then
        count=count+1
    fi

Always use [[ and ]] for string and file tests. Such as:

    if [[ "$var1" = "$var2" && -r "$var1" ]]    # ksh88
    then
        rm "$var1"
    fi
    if [[ "$var1" == "$var2" && -r "$var1" ]]   # ksh93
    then
        rm "$var1"
    fi

Never put spaces around the equal sign in variable assignments. Such as:

    typeset -i count=10
    prog="${0##*/}"

[Note: technically, variable assignment is another area where the shell doesn't require the double quotes around the right-hand side. But put them in anyway!]

Always put spaces everywhere else! Such as around the fields within [[ and ]] or (( and )). Always put spaces on both sides of command names and keywords such as if, then, else, elif, fi, while, for, select, do, done, case, in, esac, let, and any other built-in or external commands.