[Previous] [Contents] [Next]

sh

Command interpreter (POSIX)

Syntax:

sh [-aefhkmnquvx] [command_file [argument...]]

sh -c [-aefhkmnquvx] command_string
   [command_name [argument...]]

sh -i [-aefhkmquvx] [command_file [argument...]]

sh -s [-aefhkmnquvx] [argument...]

Options:

By default, the Shell is invoked interactively. To change how the Shell executes shell commands and where it reads them from, you use these options:

-c
Read commands from command_string. The special parameter $0 is set to command_name and the positional parameters ($1, $2... $n) are set to the remaining arguments.
-i
Run interactively. The Shell is also invoked interactively if no operands are specified and the Shell's standard input and standard error are attached to a console or terminal.
-s
Read commands from the standard input. If no operands are given and the -c option isn't specified, the Shell is invoked as if the -s option had been specified.

For information on the options -a, -e, -f, -h, -k, -m, -n, -q, -u, -v, and -x, see the description of the set utility in the section "Using Shell commands."

Description:

The sh utility is a command interpreter that acts as the interface between the user and QNX. A clone of the 86 KornShell (ksh86), which is a superset of the Bourne Shell, the sh utility has many capabilities. These capabilities are described throughout the following sections, arranged alphabetically:

At the end of this man page you'll find several example shell scripts.

Terminology

The following terms have special meanings in the context of sh. Becoming familiar with them will help you take full advantage of the sections that follow.

AND-OR-list
A sequence of one or more pipelines separated by the operators && and ||.
blank
Any one of the characters currently set in the IFS (Input Field Separators) environment variable. The defaults are usually the tab, space and newline characters.
command list
A sequence of one or more AND-OR-lists separated by the operators ; and &.
comment
Any word beginning with a # character. The word and all characters following it are ignored until a newline is detected.
control operator
One of the following symbols:
&  &&  (  )  ;  ;;  |  || 
  

or a newline character.

name
A sequence of letters, digits, or underscores beginning with a letter or an underscore.
parameter
A name, a digit, or any of these characters:
@  #  ?  -  $  ! 
  

If a named parameter is exported, it becomes an environment variable.

pipeline
A sequence of one or more commands separated by the control operator |. The standard output of all but the last command is connected to the standard input of the next command.
redirection operator
One of the following symbols:
<  >  >|  <<  <<-  >>
<&  >&  <>  <&-  >&-
  
simple command
A sequence of optional variable assignments and redirections, optionally followed by words and redirections, and terminated with a control operator.
word
Any sequence of characters -- other than a control operator or redirection operator -- that the Shell treats as a single unit when reading input.

Command lists

A command list is a sequence of commands or pipelines, or both. You can separate the components in a command list by either of these control operators:

;
(used for sequential lists)
&
(used for background execution)

or by either of these logical control operators:

&&
(used for AND lists)
||
(used for OR lists)

Sequential lists

If you separate the commands in a list with the ; control operator, the commands are executed sequentially, one after the other. For example:

  $ cd /tmp ; ls ; ls | wc -l
  doit.awk     junk        temp        xfile
  4
  $ 

This is identical to entering the commands on three separate lines except that the Shell outputs only a single prompt once all the commands have finished executing.

Background lists

If you terminate a single command with the &, the command is executed in the background (asynchronously). You can also use this technique to execute a grouped command list in the background:

  (cd /tmp; ls; ls | wc -l) &

For more information, see "Grouping command lists," below.

AND/OR lists

The && and || operators allow a list to execute depending on the exit code of the preceding list:

If you use: The next list is executed only if:
&& the preceding list succeeded (zero exit code)
|| the preceding list failed (nonzero exit code)

Grouping command lists

You can group command lists as follows:

(list)
Executes list in a subshell.
{list;}
Executes list in the current process environment.

For example, the following group of commands will invoke a subshell that outputs a sorted list of who is on the network:

( who -a | cut -f1 -d' ' | sed -e 1d | sort -u )

Command substitution

Command substitution allows the standard output of a command to be substituted in place of the command itself. You can perform command substitution in either of two ways:

Any trailing sequence of one or more newline characters is deleted before the output is substituted.

Examples

The command echo $(date) could produce:

    Thu Apr 11 10:23:12 EDT 1997

If placed in a shell script, the following command lets you find the name of the script:

    name=`basename -- $0`

Environment variables

Environment variables are named parameters used by the Shell. You can change these variables to modify the shell environment. When invoked, the Shell sets default values for the IFS, PATH, PS1, and PS2 variables.

CDPATH
The directory search path used by the cd builtin.
HOME
The pathname of the user's home directory
IFS
(Input Field Separators) A string treated as a list of characters that are used for splitting fields. The default characters in IFS are space, tab, and newline.
LOGNAME
The user's login name.
PATH
The directory search path used by the Shell for locating executable programs and shell scripts. For non-superusers, the default path is PATH is :/bin:/usr/bin
PS1
The primary prompt string (default is "$ " for non-root users, "# " for root).
PS2
The secondary prompt string (default is "> ").
SHELL
The pathname of the user's preferred shell.
TERM
The terminal type.
TMPDIR
The pathname of a directory that can be used by utilities that need a place to create temporary files.
TZ
The timezone setting. See also the section on "Named parameters" in the "Expansion" entry.

Expansion

Filename expansion

You use most QNX commands for manipulating files in one way or another. As such, the Shell has a filename "shorthand" that can be used to specify the files that a particular command is to operate on. This "shorthand" consists of these characters:

If one or more of these shorthand characters is used in a command line, each word containing the characters is treated as a "pattern" and is replaced with the list of filenames matching the pattern. Filenames that begin with a dot (.) aren't included in the generated list unless a dot is explicitly included as the first character of the pattern.

*
Matches any string, including the null string.
?
Matches any single character.
[...]
Matches any one of the enclosed characters. If you specify two characters separated by a dash (-), this matches the characters and any characters that fall between them (e.g. [a-c] matches "a", "b", and "c").
[!...]
Matches any character except for the enclosed characters.

Note: Note that directories, as well as files, are matched by these shorthand characters.

Examples

The following example copies all files consisting of "fred" followed by a single digit from 1 to 3 (i.e. fred1, fred2, fred3) to the /tmp directory:

    cp fred[1-3] /tmp

This next example copies all files ending with .c or .h (e.g. fred.c, barn.h, etc.):

    cp *.[ch] /tmp

This next example copies all files that don't end with .o:

    cp *.[!o] /tmp

Parameter expansion

The QNX Shell supports three kinds of parameters:

Parameter expansion is performed on words beginning with $ and enclosed in braces ({}). The word needn't be enclosed in braces if it's used in an unambiguous context.

Positional parameters

Positional parameters are the parameters specified on the command line of the Shell and are accessed using the corresponding ordinal number. That is, $1 expands to the first argument, $2 expands to the second, and so on. Positional parameters can be assigned values using the special builtin command set.

Special parameters

The following special parameters are automatically set by the Shell and provide some commonly desired functionality for shell programming. The special parameters and the values to which they expand are as follows:

$*
All the positional parameters starting from one. If the expansion occurs within double quotes, a single word with the value of each parameter separated by a space is generated. If the named parameter IFS is set, the words are separated by the first character of its value. (For more information, see the entry on "Environment variables.")
$@
All the positional parameters starting from one. If the expansion occurs within double quotes, the value of each parameter expands to a separate word.
$#
The number of positional parameters in decimal.
$?
The exit status of the last foreground command (i.e. the exit status of the last synchronous process or pipeline).
$$
The process ID, in decimal, of the invoked shell.
$!
The process ID of the last background command.
$0
The name of the shell script, or the Shell itself.

Named parameters

Named parameters are values represented by a name as defined below. The named parameter is simply expanded into its corresponding value.

Note that if a named parameter is exported (via the export builtin), it becomes an environment variable.

The simplest form of named parameter expansion is:

or

where the value, if any, of name is substituted. Here is a simple example:

    $ me=$LOGNAME
    $ echo $me
    bruce

A parameter expansion can be modified by one of the following methods:

${parameter:-word}
If parameter is unset or null, word is substituted. Otherwise, the value of parameter is used.
${parameter:=word}
If parameter is unset or null, word is assigned to parameter. Otherwise, the value of parameter is used as is. (Note that positional parameters and special parameters cannot be assigned in this way.)
${parameter:?[word]}
If parameter is unset or null, word -- or an error message from the Shell if word is omitted -- is output to standard error. Otherwise, the value of parameter is used.
${parameter:+word}
If parameter is unset or null, the null string is substituted; otherwise word is used.

Note: In the parameter expansions shown above, using the colon (:) results in a test for the parameter being unset or null. If you omit the colon, the test is only for the parameter being unset.

Here are some examples of parameter expansion modified by the above methods:

$ unset handle
$ echo ${handle:-"handle is not set or null"}
handle is not set or null
$ echo ${handle-"handle is not set"}
handle is not set
$ echo ${handle:?}
missing value for handle
$ echo ${handle:?"handle is not set or null"} 2>error
$ cat error
handle is not set or null
$ echo $handle

$ handle=cup
$ echo ${handle-"handle is not set"}
cup
$ echo ${handle+"handle is set to something"}
handle is set to something
$ handle=""
$ echo ${handle-"handle is not set"}

$ echo ${handle:-"handle is not set or null"}
handle is not set or null
$ echo ${handle:="cup"}
cup
$ echo $handle
cup

In the parameter expansions below, word can contain patterns specified with ?, *, and [...] (these characters are described under "Filename expansion"):

${#parameter}
The number of characters in the value of parameter is substituted.
${parameter%word}
Strip the smallest suffix matching word from parameter before substituting parameter.
${parameter%%word}
Strip the largest suffix matching word from parameter before substituting parameter.
${parameter#word}
Strip the smallest prefix matching word from parameter before substituting parameter.
${parameter##word}
Strip the largest prefix matching word from parameter before substituting parameter.

Here are some examples of parameter expansion modified by the above methods:

$ handle="cup of coffee"
$ echo ${#handle}
13
$ echo ${handle%"ffee"}la
cup of cola
$ echo ${handle}
cup of coffee
$ handle=foo.c
$ echo ${handle%.c}.o
foo.o
$ handle=/usr/local/bin/pcal
$ echo ${handle##*/}
pcal
$ handle=//1/home//bruce/src
$ echo /${handle#//*/}
/home//bruce/src

Tilde expansion

A tilde prefix consists of a tilde character (~) at the beginning of a word, followed by all the characters preceding the first slash (/) in the word, or all the characters if there is no slash. The tilde prefix is treated as a possible login name and is expanded into the pathname of the home directory associated with that login name. If the login name is null (i.e. the tilde prefix contains only the tilde character), the tilde prefix is expanded into the value of the HOME environment variable.

For example, if your home directory is /home/fred, the following lines are equivalent:

    cat /home/fred/myfile

    cat ~/myfile

Expressions

You can use expressions with the let command to assign a value to a variable; you can also use expressions as numeric arguments to the test command or as the value of an assignment to an integer variable.

Expressions may contain alphanumeric variable identifiers and integer constants. You can also combine them with the following operators (listed in decreasing order of precedence):

Unary operators

Operator: Description:
- unary minus
! logical not

Binary arithmetic operators

Operator: Description
* multiply
/ divide
% modulus
+ add
- subtract

Binary relational operators

Operator: Description
< less than
> greater than
<= less than or equal to
>= greater than or equal to

Equality operators

Operator: Description
== equal to
!= not equal to

Precedence

You can override the precedence of the above operators with parentheses: ( and )

Examples

Assign the value 3 to the variable a:

    let a=3

Increment a by 3

    let a=a+3

Assign the product of the variables b and c to a:

    let a=b*c

Negate the value of a:

    let a=-a

Create an integer variable a

    typeset -i a

Assign the result of b modulo 2 to a:

    a=b%2

The following example is a function to test if an integer is even (note the use of the arithmetic expression in the test):

function iseven
{
if test 0 -eq "($1 % 2)"
then
    echo $1 is even
else
    echo $1 is not even
fi
}

Note that the "return" value from this function is always true since, if a return n statement is not used to return from the function, the return value for the last command run in a function is the return value of the function.

Input line editing

When the emacs option is set (set -o emacs), the Shell provides interactive line editing. If the Shell is running on a tty, emacs line editing is enabled automatically. Note that the vi editing mode is not supported in the QNX shell.

In this line editing mode, which is similar to the emacs mode in AT&T's KornShell, various editing commands cause immediate actions without waiting for a newline. Several of these commands are bound to particular control characters when the Shell is invoked; you can change those bindings with the bind builtin command. The default bindings resemble corresponding emacs key bindings.

Note that many of the editing commands are useful only on terminals with a visible cursor. In addition, any editing commands that refer to "hashing" will work only if hashing is enabled (set -o hashall).

Editing commands

In the list of commands below, the name of each command is followed by the command's default binding, if any. Most bindings are preceded by either of the following:

^
(caret) This indicates that you should press Ctrl at the same time as indicated character.
^[
This indicates that you should press Esc, then press the indicated character.

For example, the ^G binding for the abort command indicates that you should press Ctrl-G.

abort

^G (Ctrl-G)
Aborts the search if given as a response to a request for a search-history pattern.

auto-insert

Causes the character to appear as literal input. Most ordinary characters (i.e. a, b, c...) are bound to this command.

backward-char

^B (Ctrl-B)
Moves the cursor back one character.

backward-word

^[b (Esc-B)
Moves the cursor to the beginning of a word. Words are delimited by the current setting of the IFS environment variable.

beginning-of-line

^A (Ctrl-A)
Moves the cursor to the beginning of the input line.

complete

^[^[ (Esc Esc)
Automatically completes as much as is unique of the hashed command name or filename that has been entered.

The filename is determined by the partial path that has been entered (i.e. /bin/cront would yield /bin/crontab). If the filename doesn't begin with a /, the current directory is searched.

If the entire remaining command or filename is unique, a space is printed after its completion-unless it's a directory name, in which case / is appended.

If there's no hashed command or filename with the current partial word as its prefix, a bell character is output.

complete-command

^X^[ (Ctrl-X Esc)
Completes as much as is unique of the hashed command name that has the partial word up to the cursor as its prefix. This is handy when substituting a command in the middle of a line.

Only command and function names seen since the last hash -r command are available for completion; you can use hash to register additional names.

complete-file

^X^X (Ctrl-X Ctrl-X)
Completes as much as is unique of the filename that has the partial path up to the cursor as its prefix.

delete-char-backward

^H (Ctrl-H)
Deletes the character before the cursor.

delete-char-forward

^D (Ctrl-D)
Deletes the character after the cursor.

delete-word-backward

^W (Ctrl-W)
Deletes characters before the cursor, back to the beginning of a word.

delete-word-forward

^[d (Esc D)
Deletes characters after the cursor, up to the end of a word.

down-history

^N (Ctrl-N)
Scrolls the history buffer forward one line (later). Each input line originally starts just after the last entry in the history buffer, so this command isn't useful until you've performed either search-history or up-history.

end-of-line

^E (Ctrl-E)
Moves the cursor to the end of the input line.

forward-char

^F (Ctrl-F)
Moves the cursor forward one position.

forward-word

^[f (Esc F)
Moves the cursor forward to the end of a word.

kill-line

^U (Ctrl-U)
Deletes the entire input line.

kill-to-eol

^K (Ctrl-K)
Deletes the input from the cursor to the end of the line.

list

^[? (Esc ?)
Prints a sorted, columnated list of hashed command names or filenames, if any, that can complete the partial word containing the cursor. Directory names have / appended to them, and executable file names are followed by *.

This is useful if you want to find out what the possible matches might be for a "complete" editing sequence (e.g. ^[^[).

list-command

^X? (Ctrl-X ?)
Prints a sorted, columnated list of hashed command names, if any, that can complete the partial word containing the cursor. list-file

list-file

(unbound)
Prints a sorted, columnated list of filenames, if any, that can complete the partial word containing the cursor. Filetype indicators are appended as described for "list," above. By default, this command isn't bound to a key sequence.

newline

^J or ^M (Ctrl-J or Ctrl-M)
Causes the current input line to be processed by the Shell. The cursor may be anywhere on the line.

quote

^^ (Ctrl-^)
The character entered after the command is taken literally rather than as an editing command.

redraw

^L (Ctrl-L)
Reprints the prompt string and the current input line (only if it's not the first character typed on a new line).

search-character

^] (Ctrl-])
Takes the character entered after the command and searches forward in the current line for the next occurrence of that character.

search-history

^R (Ctrl-R)
Searches the internal history list backwards for commands matching the input. An initial ^ in the search string anchors the search to the beginning of a line.

Successive search-history commands continue searching backward to the next previous occurrence of the pattern. The history buffer retains only a finite number of lines; the oldest are discarded as necessary.

Pressing Esc will leave search mode.

transpose-chars

^T (Ctrl-T)
Exchanges the character at the cursor with the previous character.

up-history

^P (Ctrl-P)
Scrolls the history buffer back one line (earlier).

yank

^Y (Ctrl-Y)
Inserts the most recently killed text string at the current cursor position (i.e. the string most recently killed by a KILL character such as ^U).

yank-pop

^[y (Esc Y)
Immediately after a yank, replaces the inserted text string with the next most recently killed text string.

Initialization files

The Shell supports initialization files that allow both system-wide and user-specific customization. In these files, you can define aliases and functions as well as initialize environment variables.

/etc/profile
This is a system startup profile. It is the first file executed by every login shell. Local conventions (e.g. default paths, message-of-the-day) are often established through this file.
$HOME/.profile
This is a user-specific startup profile. It is executed by every login shell after the /etc/profile script. Exported environment variables are often set up in this file.
$ENV
Every time a new shell is started, the new shell looks to see if the $ENV environment variable is defined. If it is, the file that it specifies will be executed. This lets you set your aliases and functions (which are not inherited) so that they remain in your environment when you escape into a new shell.

To enable this feature, you must define and export ENV. This is typically done in your .profile file, as shown in this example:

    export ENV=$HOME/.kshrc
Remember that every time a utility creates a shell on your behalf, this file will be executed. If many commands are placed in this file, you may notice some delay when these shells are started.

Pipes

A pipe is a mechanism built into the QNX filesystem that lets you connect the output of one program to the input of another without having to resort to a clumsy temporary file. A pipeline is a connection of two or more programs through pipes. The special character | informs the shell that a pipe is to be set up.

In the following example, the output of ls is piped to wc in order to count the number of lines in a file listing:

$ ls |wc -l

You can have as many programs in a pipeline as you like, as the following examples illustrate.

Count the number of times a particular user is logged on to this node:

$ who |grep steve |wc -l

Count the number of times that same user is logged on anywhere on the network. Also, save the output of the who -a command in the file /tmp/whonet:

$ who -a |tee /tmp/whonet |grep steve |wc -l

Count the number of nodes on the network and save the output of sin -h net in the file /tmp/netinfo:

$ sin -h net | tee /tmp/netinfo | \
  sed -e '/-----/,$d' | wc -l

Quoting

You use quoting to suppress the special meaning of certain characters and words to the Shell. You can use quoting to:

To quote a single character, sequences of characters, or words, you enclose them in single or double quotes. If only a single character needs to be quoted, it can be preceded with the escape character (\).

You must quote the following characters if you want them to represent themselves:

|  &  `  '  ;  \  (  )  "
  

plus spaces, tabs, and newlines.

You might need to quote the following characters, depending on their context within a shell command:

*  ?  [  #  ~  =  %  
  

Escape character (backslash)

If not quoted, a backslash character (\) preserves the literal value of the next character, unless the next character is a newline. If a newline follows the backslash, the Shell interprets this as line continuation.

Single quotes

Enclosing characters and words in single quotes (' ') preserves the literal meaning of each character and reserved word within the single quotes. A single quote cannot be included with single quotes. For example:

    echo 'What'\''s up Doc?'

results in:

    What's up Doc?

Double quotes

Enclosing characters and words in double quotes (" ") preserves the literal meaning of all characters and words within the double quotes, with the exception of the $, `, and \ characters:

This character: Retains its special meaning:
$ of introducing parameter expansion, command substitution, and arithmetic expansion
` of introducing the alternate form of command substitution (see "Command substitution")
\ as the escape character

To include a double quote character within double quotes, you precede it with the escape character. For example:

    toon=Bugs
    echo "$toon: \"What's up Doc?\""

results in:

    Bugs: "What's up Doc?"

Shell prompts

The Shell always prompts for input. By default, for non-root users, it displays this prompt:

$

This prompt is displayed whenever the Shell is waiting for input at the command line. The Shell also has a secondary prompt, which by default is set to:

>

The Shell displays this secondary prompt whenever a newline is entered and the Shell requires further input to complete the command (unless the newline has been escaped).

In the following example, the Shell presented the secondary prompt because the string wasn't terminated with a closing quotation mark.

    $ echo "QNX 4 is POSIX
    > and a whole lot more."

Redirection

When a command is run, part of its environment consists of standard files set up for its use. These files, standard input, standard output, and standard error output (stdin, stdout, stderr), are usually attached to the active terminal. When the Shell executes a command, the command inherits a copy of the Shell's file descriptors without having to open them again. Before a command is executed, its input and output can be redirected using a special notation interpreted by the Shell. The general syntax used for redirection is:

where n is an optional file descriptor number, redir-op is one of the redirection operators described below, and file is usually the name of a file.

Redirecting input

[n]<file
Opens file for reading on the specified file descriptor (n) or on standard input if the file descriptor isn't given.

Redirecting output

[n]>file
Opens file for writing on the specified file descriptor (n) or on standard output if the file descriptor isn't given. If the file exists, it's overwritten. If the file does not exist, it's created. If the noclobber option is set (see the set command) and the file already exists, [n]>file will fail.

Redirecting output, ignore noclobber

[n]>|file
Identical to [n]>file except that [n]>|file will overwrite existing files even if the noclobber option is set.

Appending output

[n]>>file
Opens file for writing on the specified file descriptor (n) or on standard output if the file descriptor isn't given. If the file exists, output is appended to the end of the file. If the file does not exist, it's created.

The here-document

[n]<<[-]word
Reads the specified file descriptor n, or the standard input if a file descriptor isn't given, until a line that is the same as word is found or the end-of-file is reached. The resulting document becomes the standard input for the next command to be executed, hence the term "here-document."

If no characters in word are quoted, all lines of the here-document have parameter expansion, arithmetic expansion, and command substitution performed on them. In this case, you must use the backslash character (\) to quote these characters:

\, $, or `

If the form [n]<<-word is used, leading tabs are stripped from the input lines and from the line containing the delimiter word. The following example will output the text between the first line, which contains the here-document operator (<<), and the last line, which consists of the delimiter (THE_END). The text between these two lines will be output without the leading tabs. This example could be used instead of a sequence of echo commands.

cat <<-THE_END
The QNX Operating System is ideal for
realtime applications. It provides
multitasking, priority-driven preemptive
scheduling, and fast context switching--all
essential ingredients of a realtime system.
THE_END

Duplicating an input or output file descriptor

[n]<&digit
[n]>&digit
The specified file descriptor n, or the standard input if n isn't given, is made to be a copy of the input file descriptor specified by digit. The second form [n]>&digit descriptor behaves similarly for duplicating an output file descriptor.

Opening a file descriptor for reading and writing

[n]<>file
Opens file for both reading and writing on the specified file descriptor or on standard input if the file descriptor isn't given.

Closing a file descriptor

[n]<&-
[n]>&-
Closes the specified file descriptor n. If a file descriptor isn't given, the standard input is closed. The second form [n]>&- behaves similarly for closing an output file descriptor.

Remote execution

The preferred method of running a program remotely is to use the on -n node utility. However, the QNX shell does, for the time being, support a builtin syntax for executing programs on remote nodes. This feature is an extension to the shell and won't be found in other systems.

This syntax can be in one of two forms:

or


Note: Both these forms of builtin shell support for remote execution are deprecated. Relying on them will reduce the portability of your code to future versions of QNX, and restrict your choice of shells which you can use with your QNX system to those supplied with the system. Use the on utility instead.

Remote execution is sometimes necessary when a utility has no way of performing the work on a remote system directly. An example of this is the rtc hw command, which needs access to the local hardware to fetch the current date and time from the clock hardware.

For example, the preferred way to load the OS clock on node 61 with the date and time from the hardware clock on the same machine is:

# on -n61 rtc hw

but the same can be accomplished (in a less portable fashion) using:

# onnode 61 rtc hw

or, even less desirably:

# //61 rtc hw

Reserved words

Reserved words are words that have special meaning to the Shell. The following words are reserved:

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

Shell scripts

A shell script is a text file that contains a sequence of shell commands. A shell script may be executed in three ways

The example on the following page is an implementation of the which utility as a QNX shell script. The example script is called cpath.

Of special interest within this shell script is the first line:

#! /bin/sh

This is a special syntax that informs the invoking shell, or the Process Manager (Proc) to spawn another shell (in this case, /bin/sh) to execute the shell script. For example, let's say the user's current shell is the Korn shell (ksh) and this shell script has been invoked by entering cpath ls at the command line. The Korn shell (or Proc's loader thread) first reads this line, then invokes the QNX shell (/bin/sh) to execute the shell script.

If a script is being run from a shell and doesn't begin with #!, then /bin/sh is used anyway. If the script is being spawned directly (through spawn*(), qnx_spawn() or exec() functions), then an exec format error will result if the script does not being with #! programname.


Note: You'll find several more example shell scripts at the end of this man page.

#! /bin/sh

# Usage message compatible with the "use" utility starts below.

#ifdef __USAGE
#%C    - display which command in PATH is executed
#
#%C    command
#Where:
#    command     is the name of the command 
#endif


oldpath=$PATH
PATH=/bin:/usr/bin

case $# in
0)      echo 'cpath command' >&2; exit 2
esac
 
for path in `echo $oldpath | sed 's/^:/.:/
                                  s/::/:.:/g
                                  s/:$/:./
                                  s/:/ /g'`
do
    if test -f $path/$1  # Is the command here?
    then
        echo $path/$1    # Yes. Display it and exit.
        exit 0
    fi
done

exit 1                   # Didn't find it...

Signals

When a command is an asynchronous command list (i.e. it is run in the background using the control operator &), the Shell prevents the SIGQUIT and SIGINT signals from interrupting the command. In the case of foreground commands, the Shell allows the same signals as its parent. Signals can also be trapped using the special builtin command trap.

Using Shell commands

A shell command is one of the following:

Commands invoked within the Shell have the following precedence:

  1. special builtin commands
  2. functions
  3. regular builtin utilities
  4. executable utilities and shell scripts

For example, when you enter:

    umask

the Shell will execute its regular builtin umask instead of the executable utility umask since regular builtins have higher precedence than executable utilities.

The Shell special builtins, functions, and regular builtins are all resolved and executed within the Shell process. Executable programs and shell scripts are found using the PATH environment variable and are spawned as subprocesses.

Control Constructs

The case conditional construct

    case word in
        pattern1)           list ;;
        pattern2|pattern3)  list ;;
        ...
    esac

The case command executes the list associated with the first pattern that matches word. Patterns are the same as those used for filename generation except that the rules concerning the slash character and a leading dot don't apply.

The if conditional construct

    if expr
    then
        list
[
    elif expr
    then
        list
]...
[
    else
        list
]
    fi

The if expr is executed; if its exit status is zero, the then list is executed and the if construct is complete.

If the exit status of if expr is nonzero, however, each elif expr is executed in turn. If the exit status of an elif expr is zero, its corresponding then list is executed.

If the exit status of an elif expr is nonzero, the else list, if any, is executed.

The for loop

    for name [ in word... ]
    do
        list
    done

The variable name is set to each word, in turn, and list is executed each time. If the in word... is omitted, then the for command executes list once for each positional parameter set (i.e. the equivalent of for name in "$@")

The while loop

    while list1
    do
        list2
    done

The while command executes list1; if list1's exit status is zero, list2 is executed and the loop is repeated. Otherwise, the loop is exited.

The until loop

    until list1
    do
        list2
    done

The until command executes list1; if list1's exit status is nonzero, list2 is executed and the loop is repeated. Otherwise, the loop is exited.

The function definition command

    name ()
    {
        list
    }

or

    function name
    {
        list
    }

Define a function name that is used by the Shell as a simple command. Any operands passed to the function can be accessed within the function using the positional parameters. The special parameter $# is also temporarily overridden to be the number of operands passed to the function. The body of the function is the list of commands.

Here's an example shell function that would do context-sensitive greps. You can pass it any number of parameters. The string is assumed to be the first argument and the rest are shifted through and grep'd:

cgrep () {
   str=$1; shift
   for f in $@; do
       grep -v $str $f | diff -c - $f  #context grep
   done
}

Regular builtin utilities

These "regular" utilities may be found external to the Shell, but they have been built into the Shell to enhance system performance.

The following regular builtin utilities are briefly described here. For a more complete description of cd, false, kill, and true, see their respective man pages.

cd

Change working directory.

cd [directory]

The cd utility changes the working directory of the current execution environment. If directory isn't specified, the value of the HOME environment variable becomes the new working directory.

false

Return a false value.

false

The false utility returns a nonzero exit status.

getopts

Parse utility options.

getopts optstring name [argument...]

The getopts utility uses the characters in optstring to parse and retrieve options and option arguments from a list of parameters. The optstring argument is a string containing the option characters to be recognized. A colon following an option character informs getopts that this option is expected to have an option argument.

By default, getopts parses the positional parameters passed to the invoking shell procedure. If one or more arguments are given, the arguments are parsed instead of the positional parameters.

Each time it's invoked, the getopts utility places the value of the next option in the shell variable specified by name; it also places the index of the next argument to be processed in the shell variable OPTIND. When the Shell is first invoked, OPTIND is initialized to 1. When an option requires an option argument, it is stored in the variable OPTARG. If no option is found, or if an option is found but it doesn't have an option argument, OPTARG is unset.

If an option character not contained in optstring is found, name is set to the question mark character (?), OPTARG is unset, and an error message is written to the standard error output. Under this condition, if the first character of optstring is a colon, OPTARG is instead set to the option character found and no error message is output.

When the getopts utility has processed all of the options, it returns with an exit status greater than zero and the OPTIND variable is set to the index of the first nonoption argument.

history

Display an entry or range of entries from the history list.

history [start_number [end_number]]

The Shell keeps a list of the text strings that have been submitted for execution -- this is known as the Shell's history. You can quickly recall and execute entries from your history (e.g. via Ctrl-P or Ctrl-R ). For more information, see the entry on "Input line editing."

When invoked without arguments, history displays the last 13 entries in the history list.

kill

Terminate or signal processes.

kill signame pid...

kill -signum pid...

kill -l

The kill utility sends the signal specified by signame or signum to the specified processes (if a pid is negative, it specifies a process group).

In the first form, signame is the symbolic name of a signal. Values of signame are recognized in case-independent fashion, with or without the SIG prefix. In the second form, signum is the decimal number of the signal to be set. If no signal is specified, the termination signal is set by default.

If the -l (el) option is specified, the kill utility writes a list of all supported signal names to the standard output.

onnode

Start a process on another node.

onnode node command [argument...]

The onnode builtin is a deprecated shell feature which is a quick way of doing the equivalent of what on -n node does. It is used for remote execution. It executes the command with the specified arguments on the specified node. The standard input, standard output, and standard error output are inherited from the invoking shell. The syntax onnode 1 sin is the same as:

    //1 sin

which is similarly discouraged.

Instead of these builtins, you should use the on utility to run a command on another node.

ontty

Start a process on another tty.

ontty device command [argument...]

The ontty builtin is a deprecated shell feature which is a quick way of doing the equivalent of what on -t tty does. It executes the command with the specified arguments on the named tty. The command is detached from the invoking terminal. The ontty builtin operates by redirecting the program's stdin, stdout, and stderr to the indicated device. If the device is remote, the ontty command remotely executes the program on that node.

In the following example, mymonitor is run on the local node, with its input and output attached to /dev/ser1 of node 4:

    ontty //4/dev/ser1 mymonitor

In the next example, monitor runs on node 4 while its I/O is attached to /dev/ser1 on the local node:

    onnode 4 ontty /dev/ser1 monitor

Instead of this builtin, you should use on utility to run a command on another tty.

read

Read a line from standard input.

read [-r] var... [? "prompt_string"]

The read utility reads a single line from the standard input. The line is split into words using the separator characters contained in the IFS variable. The first word is assigned to the first var, the second word to the second var, and so forth. Any additional words are appended to the last var. If the number of var arguments specified is greater than the number of words in the input line, the extra var arguments are assigned the null string.

If the -r option is specified, the backslash character (\) is treated like any other character in the input line instead of being interpreted as an escape character.

If a question mark (?) follows the variables, the shell will print the text following the question mark as a prompt before reading the input. For example, to read data into a variable $a, one might use:

$ read a?"Enter value for a:"
Enter value for a: blahblah
$ echo $a
blahblah

test

Test condition.

test expression [expression]

The test utility evaluates the expression and returns zero status if true and nonzero status otherwise. It is normally used as the controlling command of the if and while statements.

The following basic expressions are available:

Expression Meaning
-r file file exists and is readable
-w file file exists and is writable
-x file file exists and is executable
-f file file is a regular file
-d file file is a directory
-c file file is a character special device
-b file file is a block special device
-p file file is a named pipe
-u file file mode has setuid bit
-g file file mode has setgid bit
-k file file mode has sticky bit
-s file file is not empty
-L file file is a symbolic link
-S file file is a socket
file1 -nt file2 file1 is newer than file2
file1 -ot file2 file1 is older than file2
file1 -ef file2 file1 is the same file as file2
-t filedes file descriptor is a tty device
string string is not null
-z string string is null
-n string string is not null
string1=string2 string1 and string2 are equal
string1!=string2 string1 and string2 are not equal
num1 -eq num2 num1 and num2 compare equal
num1 -ne num2 num1 and num2 compare not equal
num1 -ge num2 num1 compares greater than or equal to num2
num1 -gt num2 num1 compares greater than num2
num1 -le num2 num1 compares less than or equal to num2
num1 -lt num2 num1 compares less than num2

You can combine the above basic expressions with these operators:

Operator(s) Example Description
-o expr -o expr logical OR
-a expr -a expr logical AND
! !expr logical NOT
(...) (expr) precedence grouping

true

Return true value.

true

The true utility returns a zero exit status.

wait

Await process termination.

wait [jobid...]

The wait builtin waits for the specified jobs to terminate and returns the exit status of the process requested by the last jobid operand. If no operands are specified, it waits for all of the child processes of the invoking shell to terminate. The jobid may be specified in the following forms (the % character is optional):

%+
Select the current job
%-
Select the previous job
%n
Select job number n (see output of jobs builtin).
%string
Select job whose command starts with string.
%?string
Select job whose command contains string.

Special builtin commands

The following special commands are "built into" the Shell; that is, the Shell interprets and executes them internally. Because these commands are tightly bound to the shell interface, they are called special builtin commands. The output of these commands, if any, is written to the standard output; you can apply normal redirection and piping operations.

alias

List aliases.

alias [name=value...]

Without arguments, alias lists all aliases and their values. If a name is specified without a value, its value is listed. Any name specified with a value defines an alias. System V command hashing is implemented (see hash).

Alias expansion occurs when the first word of a statement is a defined alias, except when that alias is already being expanded. It also occurs after the expansion of an alias whose definition ends with a space.

List all aliases:

    alias

Show the current definition of a specific alias:

    alias alias_name

Remove an alias:

    unalias alias_name

Some common aliases:

    alias l="/bin/ls -lFR"
    alias lf="/bin/ls -CF"
    alias m=less

bind

Create bindings for commands or text strings.

bind

bind string=editing_command

bind -m string=substitute

Without arguments, the bind command lists the current bindings.

With the string=editing_command syntax, the specified editing command is bound to the given string. If the string is subsequently input, the editing command will be immediately invoked. The string, which should consist of a character, may be preceded by either of the following:

^
(caret) This indicates that Ctrl should be pressed at the same time as the string.
^[
This indicates that Esc should be pressed before the string.

For example, if you created the following binding for the forward-char command:

    bind ^f=forward-char

You would press Ctrl-F to use the binding.

With the -m option, the given input string, whenever subsequently specified, will be immediately replaced by the given substitute string. The substitute string may contain editing commands.

Editing commands are described in the entry on "Input line editing."

break

Exit from a for, while, or until loop

break [n]

The break command exits from the smallest enclosing for, while, or until loop, or from the nth enclosing loop if n is specified (default for n is 1). If n is greater than the number of enclosing loops, then the largest enclosing loop is exited. Execution continues with the command immediately following the exited loop.

builtin

Execute a command as a builtin command.

builtin command [argument...]

The builtin command causes the Shell to treat the specified command as a builtin command, suppressing the shell function lookup that is part of the default command lookup process.

: (colon)

Null command.

:

The : (colon) command does nothing; it is simply a null command or place holder. It always returns an exit status of zero.

continue

Continue a for, while, or until loop.

continue [n]

The continue command returns to the top of the smallest enclosing for, while, or until loop, or to the top of the nth enclosing loop if n is specified (default for n is 1). If n is greater than the number of enclosing loops, then execution resumes at the top of the largest enclosing loop.

. (dot)

Execute commands in the current environment.

. file

The . (dot) command reads and executes the commands from file within the current environment. The search path contained in the environment variable PATH is used to find the directory containing file. This command doesn't require that file be executable.

eval

Execute a command from concatenated arguments.

eval [argument...]

The eval command constructs a command by concatenating the specified arguments. The constructed command is then read as input to the Shell and executed.

exec

Execute a command and/or manipulate file descriptors.

exec [command [argument...]]

The exec command opens, closes, and/or copies file descriptors as specified by any I/O redirections given as part of argument. If a command is specified, that command is spawned as a replacement for the Shell. Any specified arguments are passed to the spawned process.

exit

Cause the Shell to exit.

exit [n]

The exit command causes the Shell to exit with the exit status specified by n. If n isn't specified, the exit status is that of the last command executed.

export

Mark environment variables for export.

export name[=word]...

export -p

The export command marks the specified names for export, which will cause them to be in the environment of subsequently executed commands. If you specify the -p option, the names and values of all exported variables are written to the standard output.

hash

Print hashed command pathnames.

hash [-r] [name...]

Without arguments, hash lists any hashed executable command pathnames. If any names are given, each is searched as if it were a command name and is added to the hash table if it is an executable command. The -r option removes all commands from the hash table.

Hashing is enabled by the set builtin command (set -o hashall). When hashing is enabled, the location of each executed command is memorized (i.e. hashed). In addition, the hash table is searched in preference to the PATH when any command is invoked.

jobs

Display status of jobs in the current session.

The jobs command displays the status of jobs that were started under the current shell.

let

Evaluate expressions.

let [argument...]

Without arguments, let returns a nonzero exit status. If arguments are included, each expression is evaluated (see the "Expressions" entry). A zero status is returned if the last expression evaluates to a nonzero value; otherwise a nonzero status is returned.

print

Print arguments.

print [argument...]

The print command prints its arguments on the standard output, separated by spaces, and terminated with a newline.

readonly

Mark environment variables as read-only.

readonly name[=word]...

readonly -p

The readonly command marks the specified names as "read-only." Environment variables marked with the readonly attribute cannot be changed by a subsequent assignment nor can they be unset by the unset command.

If the -p option is given, the names and values of all readonly variables are written to the standard output.

reopen

Attach input and output to a device. (Deprecated)

reopen device

The reopen command closes standard input, standard output, and standard error and attaches them to the specified device. This command is often used in sysinit files.

The following would reopen standard I/O to the new device //0/dev/con1:

   reopen //0/dev/con1

This builtin is deprecated in favor of its non-QNX-specific equivalent,

   exec <>//0/dev/con1 >&0 2>&0

return

Return from a function.

return [n]

The return command causes the Shell to exit the current function or dot script. The return value is either the value specified by n or the exit status of the last command executed if n isn't specified.

set

Set/unset options and positional parameters.

set [-aefhkmnquvx] [-o option_name]... [argument...]

set [+aefhkmnquvx] [+o> option_name]... [argument...]

set -- [argument...]

The set command sets and/or unsets the shell options. An option preceded by:

-
sets the corresponding attribute
+
unsets the corresponding attribute

The current set of option flags is kept in the special parameter -.


Note: If any arguments are given, the positional parameters are overridden with these values and the special parameter $n is updated. Note also that the double dash (--) is used to separate the options from the arguments.

set Option Description
-- Unset all positional parameters. If any arguments are specified, define where they begin.
-a Set the export attribute for each variable that is created or assigned a new value.
-e Exit immediately if a command returns with a nonzero exit status.
-f Don't expand filenames.
-h Add command pathnames to the hash table
-k Allow variable assignments to be recognized anywhere in the command.
-m Monitor background jobs.
-n Read commands but don't execute them. This option can be used to check a shell script for syntax errors before actually executing it. This option is ignored in interactive mode.
-o option_name Set the specified option. (See entries below for details.)
-o allexport (same as -a)
-o errexit (same as -e)
-o keyword (same as -k)
-o monitor (same as -m)
-o noexec (same as -n)
-o noglob (same as -f)
-o nounset (same as -u)
-o verbose (same as -v)
-o trackall (same as -h)
-o xtrace (same as -x)
-o bgnice Run background jobs with lower priority.
-o emacs Enable emacs-style line editing (default for ttys).
-o hashall Enable command hashing.
-o ignoreeof Don't exit on end-of-file (the Shell will exit only if you enter exit).
-o noclobber Don't overwrite existing files. This prevents the Shell's > redirection operator from overwriting existing files. You can use the >| redirection operator to override this option for individual files. To display current settings for -o, type set -o.
-q Ignore the QUIT signal.
-u Treat the expansion of unset named parameters as an error.
-v Be verbose; write input lines to standard error before execution.
-x Enable execution trace; write each command and its arguments to the standard error output before execution.

times

Print system and user times.

times

The times command lists the system and user times for your invocation of the Shell. If any child processes created by the Shell have died, their times are also listed.

shift

Shift positional parameters.

shift [n]

The shift command shifts positional parameters down by n positions. If n isn't specified, it defaults to 1. Positional parameter 1 becomes parameter (1+n), parameter 2 becomes parameter (2+n), and so forth. The special parameter $# is updated to contain the new number of positional parameters.

typeset

Print variables and their attributes.

typeset [+firx] [name[=value]...]

If no arguments are given, typeset lists all variables and their attributes.

If names are given, typeset sets the attributes of the named variables. Variables may also be assigned a value. If used inside a function, the created variables are local to the function.

If options but no names are given, typeset lists variables with specified attributes and their values (unless + is used).

The attributes are as follows:

-f
List functions instead of variables.
-i
Store the variable's value as an integer.
-r
Make the variable read-only so that it cannot be reassigned a value.
-x
Export the variable to the environment.

trap

Trap signals.

trap [action condition...]

The trap command causes the specified action to be executed when one of the specified conditions occurs. A condition is either a signal specified using a symbolic name, with or without the SIG prefix, or the string "EXIT". The action is simply a Shell command and is processed by the Shell in a manner equivalent to:

    eval "$action"

Signals that were ignored on entry to a non-interactive shell cannot be trapped or reset, whereas an interactive shell may reset or catch them. Traps remain in place for a given shell until they are explicitly changed with another trap command.

If no arguments are given, the trap command writes a list of actions associated with each condition to the standard output.

unalias

Remove aliases.

unalias name...

The unalias command removes the aliases for each given name.

unset

Unset values and attributes of named parameters and functions.

unset [-f] name...

The unset command unsets each named parameter or function specified. If the -f option is specified, then the function name is unset. If the -f option is not specified, then name refers to a named parameter. If that named parameter doesn't exist, then the function of that name, if any, is unset.

You can't use the unset command to unset read-only named parameters, positional parameters, and special parameters.

whence

Print command types.

whence [-V] name...

The whence command prints the type of command for each given name. If you specify -V, function and alias values are also printed.

Sample shell scripts

You can find the source for the following shell scripts in the /usr/demo/scripts directory.

lib2list -- create sorted list of routine names

#! /bin/ksh
#set -vx

#
#    Use: lib2list <library_name>
#
#    Create a sorted list of routine names from a Watcom library
#
cd /usr/lib

if test $# -eq 0
then
    echo Use: ${0##*/} "<library_name>"
    exit 0
fi

tmp=$TMPDIR/l2l.$NODE.$$-

#  The "trap" routine to clean up if user hits ^C (intr)
trapper ()
{
    rm -f ${tmp}*
    unset tmp
    exit 1
}

trap trapper INT QUIT

#  Check if the library is accessible. Try the library name
#  as first given, then try it with an appended ".lib"
#  suffix, then try it with the "large model" character
#  inserted, then give up.

if test -f $1
then
    lib=$1
elif test -f $1.lib
then
    lib=$1.lib
elif test -f $1l.lib
then
    lib=$1l.lib
elif
then
    echo ${0##*/}: unable to open library \"$1\".
    exit 1
fi

echo Library name list for \"${lib}\":

#   Use "sed" to filter the list of names from the
#   "wlib" output. Then "cut" out the two columns into
#   a new single-column file.
#
wlib ${lib} |sed -e '/^WATCOM/,/^WATCOM/d' -e '/^$/,$d'\
-e 's/  */:/g' >${tmp}A
cut -d: -f1 ${tmp}A >${tmp}B
cut -d: -f2 ${tmp}A >>${tmp}B
#

#  Use the following "sed" line instead to see all the names.
#  (i.e. double and treble underscore names)
#
#sed -e '/^ *$/d' -e '1,$s/_*\.\.*.*$//' ${tmp}B |sort

sed -e '/^ *$/d' -e '1,$s/_*\.\.*.*$//' -e '/^__.*$/d' ${tmp}B\
|sort

#  Clean up the files and variables we used.
rm -f ${tmp}*
unset tmp

exit 0

reverse -- look at options and process a string

#! /bin/sh
#ifdef __USAGE
#%C [options] your_word
#
#Options:
# -b      What the word begins with
# -c      Number of characters in the word
# -r      The word in reverse
#endif

#set -v

me=${0##*/}

print_usage ()
{
    echo "$me [options] your_word"
    echo
    echo "Options:"
    echo " -b      What the word begins with"
    echo " -c      Number of characters in the word"
    echo " -r      The word in reverse"
    exit 0
}

trapper ()
{
    echo Script interrupted by user!
    echo exiting...

    exit 0
}

#
#   Reverse the string passed in the positional parameters
#   and output the resulting string on the standard output
#   (file descriptor 1).
#
reverse ()
{
    typeset newword word x y
    typeset -i len

    newword=""
    word="$*"
    len=${#word}

    while test $len -gt 0
    do
        x=${word%?}
        y=${word##$x}
        word=$x
        newword=$newword$y
        let len=len-1
    done

    echo $newword
}

#
#   The main body of the shell script
#

trap trapper INT QUIT

if test $# -lt 1
then
    print_usage
fi

#   Check for options
#
typeset -i bflag=0 cflag=0 rflag=0

while getopts bcrx:y: opt $*
do
    case $opt in
         b)  bflag=1 ;;
        +b)  bflag=0 ;;
         c)  cflag=1 ;;
             r)  rflag=1 ;;
         x)  echo Argument to \"-x\" option is \"$OPTARG\"  ;;
         y)  echo Argument to \"-y\" option is \"$OPTARG\"  ;;
        \?)  echo ; echo ; print_usage ;;
    esac
done

let i=OPTIND-1

shift $i
word="$*"

if test $bflag -eq 0 -a $cflag -eq 0 -a $rflag -eq 0
then
    bflag=1;
    cflag=1;
    rflag=1;
fi

echo Your word \"$word\":

if test $bflag -eq 1; then
    case $word in
      [0123456789]*) echo "  begins with a number." ;;
      [a-zA-Z]*)     echo "  begins with a letter." ;;
      *)             echo "  starts with a special character." ;;
    esac
fi

if test $cflag -eq 1; then
    echo "    has ${#word} characters in it."
fi

if test $rflag -eq 1; then
    echo "    in reverse is \"`reverse $word`\"."
fi

unset me bflag cflag rflag

exit 0

Examples:

Invoke a subshell from the command line:

    sh

Invoke a subshell with a command script:

    sh /etc/backup

Invoke a subshell with a command string:

    sh -c "cd /etc; ls -alF"

See also:

esh, ksh, uesh


[Previous] [Contents] [Next]