home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
SHELLS
/
sh73.lzh
/
DOC
/
sh.doc
< prev
next >
Wrap
Text File
|
1998-05-26
|
86KB
|
2,059 lines
An sh-like shell for OS-9
Version 2.1, edition 73, last revision on May 27, 1998
1. Origin, support, no warranty
-----------------------------------
This program is based on the shell that was part of the initial release of
Andrew S. Tannenbaum's MINIX. It has been adapted to OS-9 through a number of
contributions of OS-9 enthusiasts, mostly by Reimer Mellin and released as
part of the TOP software package. In 1992, a user's manual was written by
Carsten Emde who also started a changelog protocol and continued development
and maintenance of the 'sh' sources. From this time onwards, 'sh' is available
as EFFO (European Forum For OS-9) PD disk. Since then, after more than 2000
hours of programming and testing, 'sh' became nearly 100% compatible with the
standard OS-9 shell and the Bourne shell; in addition, it now offers a large
part of the functionality contained in UNIX shells such as 'csh' and 'bash'.
Since 1994, 'sh for OS-9' is part of the OS-9 release of reccoware's MGR
graphical window system and in June 1997, 'sh' was first uploaded to
ftp://os9archive.rtsi.com. A limited support and, possibly, bug fixing
are offered (but not guaranteed) via E-Mail (carsten@ceag.ch).
Because the program is licensed free of charge, there is no warranty for the
program, to the extent permitted by applicable law. Except when otherwise
stated in writing the copyright holders and/or other parties provide the
program "as is" without warranty of any kind, either expressed or implied,
including, but not limited to, the implied warranties of merchantability and
fitness for a particular purpose. The entire risk as to the quality and
performance of the program is with you. Should the program prove defective,
you assume the cost of all necessary servicing, repair or correction.
In no event unless required by applicable law or agreed to in writing will any
copyright holder, or any other party who may modify and/or redistribute the
program as permitted above, be liable to you for damages, including any
general, special, incidental or consequential damages arising out of the use
or inability to use the program (including but not limited to loss of data or
data being rendered inaccurate or losses sustained by you or third parties or
a failure of the program to operate with any other programs), even if such
holder or other party has been advised of the possibility of such damages.
2. Introduction
-------------------
The 'sh' shell program was intended as a surrogate for Mware's shell. Maximum
attention was, therefore, drawn to offer the basic functionality of the Mware
shell and also of the Bourne shell in order to allow using both OS-9 and UNIX
shell scripts. In addition, useful features of the 'csh' and the 'bash' shell
have been integrated. Compatibility of these four sources was, however, not
always possible: the Bourne shell standard output append symbol ('>>'), for
example, is the standard error redirection symbol of the Mware shell. In
addition, command line editing using uEmacs commands was not always compatible
to the SCF line editing commands of the Mware shell: the Mware shell's redraw
current line command (Ctrl-A) sets the uEmacs cursor to the beginning of a
line. As a general programming rule, compatibility to 'bash' was given the
highest priority followed by compatibility to 'shell'. There are, however, much
more compatibilities than incompatibilities; normally, it does not take more
than a day or two to become familiar with 'sh' for OS-9.
3. Getting started
----------------------
3.1. Installation
The 'sh' program is located in the CMDS directory of the distribution disk.
It does not require other modules such as trap handlers to run. It should
be copied to the system's standard execution directory in such a way that it
can be started by typing the
$ sh
command. Normally, however, 'sh' is started directly from the login procedure
that is defined in the password file. A typical entry in the password file
could have the following definitions:
name,*PASSWD*,<gid>.<uid>,<prio>,.,/dd,sh -ep="<$HOST/$USER/sh@>$CWD:"
It may also be a good idea to copy the suggested profile file that is
named 'dot.profile' from the SYS directory to the user's home directory:
$ copy /d0/SYS/dot.profile ~/.profile
This script contains a number of useful settings. There is also an
example login file called 'dot.login' but this file should better not be
copied to '~/.login' but only be used as an example, since many settings
are system-specific. The file '.login' in the user's home directory is
only executed by the login shell, i.e. the shell that has been forked by
the 'login' program. There is also a way to make system-wide default
definitions by creating the file '/dd/SYS/profile'. Settings in this
file are evaluated first so that they may be overwritten by alternative
settings in a particular user's '~/.profile' file. Subsequently started
'sh' tasks for script file execution do not read '~/.profile', they only
evaluate '/dd/SYS/profile'. Therefore, the latter must not include
functions, grave construct, read commands or similar; it is merely
intended for alias and environment settings that are user-independent.
When 'sh' exits from a regular interactive session the files '.logout'
and '/dd/SYS/sh.logout' are executed, if available. The contained
commands of all named procedures are executed in the same way as if they
had been entered manually. The '-r' command line option can be set to
completely disable processing of all named profile files including
'~/.login' etc. If a user-defined profile file is specified using the
'-f=<profile>' command line option, this file is evaluated last.
3.2. Supplementary programs
In addition, the distribution disk contains the following binary programs that
may be required to run UNIX scripts under OS-9:
Name Function
basename Transform a fully-qualified file name into the name of its
last element and, optionally, omit suffix
dirname Transform a fully-qualified file name into the name of its
directory
cat Same as merge, needed for the creation of here files
strcmp Extended string comparisons
The programs basename, dirname and strcmp kindly have been contributed by
M.C. Gregorie.
3.3. Example scripts
Finally, the distribution disk contains a directory SCRIPTS where a number
of 'sh' scripts can be found. They are mainly intended as examples and for
test purposes but some of them may also be copied into the system's
standard execution directory and used as if they were regular programs:
Name Function
find Find a file in the directory tree
which Search for the location of an executable program
dev Same as devs but with argument
irq Same as irqs but with argument
The 'find' script contains examples for using both the strcmp program and a
recursive 'sh' function. As a disadvantage, it is relatively slow so that
for everyday's use or on high-volume hard disks this script is better replaced
by a program. There is also an example for an 'sh' function that makes the
'del' utility interactive and is intended to be added to a user's local
profile file.
4. Command line options
---------------------------
The following command line arguments are available:
$ sh -?
Syntax: sh [<opts>] [<scriptfile>] [<arg1>] ... [<argn>]
Function: Operating system user interface (shell)
Options:
-b block input path while editing (default)
-C redirected output requires '-' to overwrite file
-c exit after reading and executing one command
-d[=<mode>] enable debug output [for <mode>]
-e[=<path>] print error explanations [using file <path>]
-f=<profile> process profile file <profile>
-g command completion includes execution directories
-h=<n> set the # of history lines to <n>
-i do not suppress shell messages (default if interactive)
-l require 'logout' to logout (default automatic)
-p[=<prompt>] print prompt <prompt>
-r do not process default profile files
-s stop command execution
-t echo input lines
-u display references to unset variables
-v verbose mode (same as '-t')
-w kill all child processes and abort if carrier lost
-x exit on error (default if non-interactive)
-y try to make standard input path a tty
All options may be prefixed by an 'n' character to invert their sense
Some of the options can also be set by environment variables or by built-in
commands:
Option Environment variable Built-in command
-e=<path> setenv EMSG_FILE <path>
-h=<n> setenv HISTORY <num> history <n>
-p=<prompt> setenv PS1 <prompt>
In addition, the 'set <option>' syntax can be used to set options within the
current 'sh' session. If 'set -' is entered, all options except '-l' are set
to their default values as described above. The environment variable HISTORY,
by default, reflects the current size of the history buffer; setting it to
another value does not influence the current history buffer size, but is taken
as default value in any subsequently called interactive 'sh' session.
4.1. Block input path while editing (-b)
Normally, another program's output cannot be redirected to the standard and
error output paths of an 'sh' session, while 'sh' is reading from its standard
input path, e.g. during command line editing. The '-nb' option can be specified
to change this behaviour; it causes 'sh' to use another read procedure so that
the terminal is not blocked and another program can write to it. This option
may be helpful to simultaneously use a terminal for both displaying messages
on screen and running an 'sh' session. By default, the '-b' option is set.
4.2. Disallow files to be overwritten by redirected output (-C)
By default, 'sh' will overwrite any existing file to which output is
redirected using the '>', '2>', or '>>' syntax. If the '-C' option is set,
however, 'sh' will write an error message and leave the file intact. This
option is identical to 'bash' and also allows to simulate the redirection
behavior of the Mware shell. A file can be forced to be overwritten, even
if the '-C' option is set, by using the '>-', '2>-' or '>>-' syntax.
4.3. Exit after reading and executing one command (-c)
The '-c' option forces 'sh' to interpret the subsequent command line option
as a command, to execute it as it were a script command and to stop execution
thereafter immediately. Therefore, the command
sh -c 'echo output string '
will display the string 'output string' on screen, while
sh -c echo output string
executes 'echo' and, therefore, does not display anything on screen.
4.4. Enable debug output (-d[=<mode>])
If an interactive command or an 'sh' script does not execute correctly, the
debug option may be used: The command 'set -d' enables debug messages in the
current shell, and the command 'sh -d <proc>' shows debug messages during
execution of the procedure <proc>. Debug messages of any child shell process
(explicit and implicit ones) are enabled by setting the environment variable
SHDEBUG to a non-zero value or to 'on' or 'ON' They are disabled when SHDEBUG
is unset, set to 'off', 'OFF' or '0'.
In addition, the 'set -d=<mode>' syntax is available to separately enable and
disable specific debug modes:
<mode> Debug category Value
args Command line arguments 1
evalg Grave construct before being evaluated 2
fork Command being executed using chainc() of forkc() 4
grave Evaluated grave construct before being executed 8
insert String to be inserted, e.g. when replacing alias 16
match String subjected to global expression match 32
search Attempts to locate a file for execution or a dir for chd 64
trace Intermediate command to be executed 128
These modes are stored internally as a bit pattern; the SHDEBUG environment
variable is, by default, set to the above given value (or-ed together)
whenever the debug mode changes. If, for example, 'match' and 'search' debug
modes are requested during execution of the procedure <proc>, the command
sh -d=search -d=fork <proc>
can be entered. The commands
setenv SHDEBUG 68
<proc>
have, however, exactly the same effect, but only in the second example remains
the debug mode enabled during all subsequent calls to 'sh' (unless SHDEBUG is
reset to 0 or unset). Finally, the commands
set -d=search -d=fork
<proc>
have, again, the same effect during execution of the procedure <proc> but, in
addition, debugging is enabled in the current shell.
4.5. Print error explanations (-e[=<path>])
By default, the '-e' option is set to the environment variable EMSG_FILE or to
'/dd/SYS/errmsg' if EMSG_FILE is not set, but it can be set to any other file
that contains OS-9 error messages in the required format.
4.6. Process profile file (-f=<profile>)
The file specified as <profile> is processed before 'sh' starts command
execution but after the default profile files '~/login', '/dd/SYS/profile' and
'~/.profile' have been processed. This makes it possible to overwrite settings
that have been made in one of the default profile files.
4.7. Command completion includes exec dirs (-g)
Whenever 'sh' is in line editing mode, the cursor is at the first position of
the input line or immediately follows a backquote, and the TAB key is hit,
command completion is activated. By default, commands are searched in the
alias list, in the list of currently available functions and in the list of
built-in commands. The '-g' option is used to additionally include files in
one of the execution directories (any of the PATH directories and execution
directory).
4.8. Set the # of history lines (-h=<n>)
The default number of history lines is the number specified in the HISTORY
environment variable or 0, if undefined. The '-h=<n>' option can be used to
define any number of history lines between 1 and 500.
4.9. Do not suppress shell messages (-i)
When a program returns another value than 0 or 1 during an interactive 'sh'
session, this error number and, optionally, the error code are displayed on
screen, since the '-i' option is automatically set, if 'sh' runs interactively.
The '-ni' option that is set by default only during execution of an 'sh'
script can be used to explicitly suppress shell messages. On the other hand,
the '-i' option can be set to explicitly force error messages even during
script execution.
4.10. Require "logout" to logout (-l)
The '-l' option is automatically set, if at least one keycap entry starts with
the escape character; otherwise, it is unset so that an 'sh' session can be
stopped just by entering the eof character (normally Esc).
4.11. Define prompt (-p[=<prompt>])
By default, the '-p' option is set to the environment variable PS1 or, if not
set, to '@# ' for a super-user and to '@% ' for any other user, respectively.
The program entry in the above given password file
sh -ep="<$HOST/$USER/sh@>$CWD:"
will invoke 'sh', for example, with the prompt
<thle27/carsten/sh1>/h0/SH/DOC:
and define the standard error message file '/dd/SYS/errmsg' for the generation
of error texts.
4.12. Do not process default profile files (-r)
Normally, the files '~/login', '/dd/SYS/profile' and '~/.profile', and the files
'/dd/SYS/sh.logout' and '~/.logout' are executed before 'sh' begins command
execution and before it exits, respectively. If the '-r' option is specified,
however, none of the named files are processed.
4.13. Stop command execution (-s)
This option causes 'sh' to immediately stop command execution; it is only
available during script execution and can, for example, be used for testing and
debugging purposes. Any command after
set -s
is prevented from being executed. It must, however, be noticed that this
command is irreversible, since once command execution has beed stopped, no
other command can be executed - even not a
set -ns
command.
4.14. Echo input lines (-t)
Every input line is echoed to the output path of the current 'sh' session.
4.15. Display references to unset variables (-u)
Normally, a reference to an undefined variable does not result in an error
message but the variable is defined and an empty string is assigned to it. In
consequence, it is not possible to differentiate between an undefined variable
and a variable that intentionally has been set to contain an empty string,
e.g. using the assign command
var=""
If, however, the '-u' option is specified, such differentiation is possible,
since this options causes 'sh' to produce an error message whenever an
undefined variable is referenced.
4.16. Verbose mode (-v)
Every input line is echoed to the output path of the current 'sh' session
(same as '-t' option).
4.17. Kill all child processes and abort if carrier lost (-w)
To become effective, this option requires that 'sh' is the primary (login)
shell and that the driver of the standard input port supports the installation
of a data-carrier-detect interrupt. If this is the case and the carrier
gets lost, 'sh' sends a HANGUP signal to all child processes and aborts with
error E_HANGUP (220).
4.18. Exit on error (-x)
When this option is set and an error occurs, the current 'sh' session exits
immediately. This is the default behaviour during execution of a shell script,
while an interactive 'sh', by default, does not exit on error.
4.19. Try to make standard input path a tty (-y)
The 'sh' built-in command 'read' requires that standard input path is a
terminal. If an 'sh' script containing the 'read' command is started by
another program that does not provide correct setting of the standard input
path but standard output or standard error output path is a terminal, the '-y'
option can be specified in which case 'sh' checks standard output and standard
error path and uses one of them for input, if possible.
5. The termcap data base and command line editing and history
-----------------------------------------------------------------
5.1. The termcap data base
The termcap data base is used for two different purposes; first, to store
specific commands that can be sent to the terminal, e.g. for cursor movement,
and, second, for the interpretation of special key sequences that are sent
by the terminal, e.g. from the arrow keys. The latter are needed for command
line editing and will be covered in the next paragraph. 'sh' for OS-9 supports
the following terminal commands that are searched in the termcap data base
when the program starts and whenever the environment variable TERM is modified:
Action Default Termcap name
Pad string ............................. None pc
Clear to end of line ................... None ce
Backspace cursor ....................... Ctrl-H bc
Enter standout mode .................... None so
End standout ........................... None se
Bell ................................... Ctrl-G bl
Clear screen ........................... None cl
Special keys on HP terminals ........... None hs
Enable above special keys .............. None hx
Normal cursor style for insert mode .... None cQ
Cursor style for overstrike mode ....... None cI
Start keypad transmit mode ............. None ks
End keypad transmit mode ............... None ke
The strings to start and to stop keypad transmit mode are sent, if set, after
'sh' enters interactive mode and before 'sh' is finishing, respectively. The
'ks' string is also sent whenever the TERM environment variable is modified.
5.2. Command line editing and history
One of the most important features of 'sh' for OS-9 is the command line
editing and history function. Please note that editing of the current command
line is always active; the history function is only active, if enabled using
the '-h=<lines>' option when 'sh' is started or using the 'history <lines>'
syntax at a later time.
The following commands are available; default keys are used, if the particular
termcap entry is not specified.
Command Default key Termcap name
Delete previous character ................ 'bse' option -
Delete character under cursor............. Del (0x7f) kD
Cursor backward .......................... Ctrl-b kl
Cursor forward ........................... Ctrl-f kr
Next history line ........................ Ctrl-n kd
Previous history line .................... Ctrl-p ku
Cursor to start of line .................. Ctrl-a kh
Alternate cursor to start of line ........ Ctrl-a ka
Cursor to end of line .................... Ctrl-z kH
Alternate cursor to end of line .......... Ctrl-e kA
Clear to end of line ..................... Ctrl-k kE
Reset terminal ........................... Ctrl-g kS
Delete current line ...................... 'del' option kL
Transpose current and previous character . Ctrl-t kT
Toggle insert/overwrite mode ............. Ctrl-v kI
Complete name ............................ Ctrl-i (TAB) ta
Clear screen ............................. Ctrl-l kc
Insert from paste buffer ................. Ctrl-y ki
Abandon edit line ........................ Ctrl-c kq
Reverse-incremental history search ....... Ctrl-r kQ
Word delete .............................. Esc,d kX
Uppercase word ........................... Esc,u kU
Lowercase word ........................... Esc,l kY
Capitalize word .......................... Esc,c kC
Word forward (next word).................. Esc,f kF
Word backward (previous word) ............ Esc,b kB
New line ................................. 'eor' option -
Logout ................................... 'eof' option -
5.3. Detailed description of all line editing commands
Delete previous character ('bse' from terminal path options)
The character to the left of the cursor, if any, is removed from the current
edit line and the cursor is moved one position to the left. This function is
normally assigned to the 'Backspace' key.
Delete character under cursor (Del/termcap kD)
The character under the cursor is deleted form the current edit line but the
cursor position remains unchanged. This function is normally assigned to the
'Delete' key.
Cursor backward (Ctrl-b/termcap kl)
The cursor is moved one character to the left, if not already at the leftmost
position. This function is normally assigned to the 'Arrow left' key.
Cursor forward (Ctrl-f/termcap kr)
The cursor is moved one character to the right, if not already at the rightmost
position. This function is normally assigned to the 'Arrow right' key.
Next history line (Ctrl-n/termcap kd)
The current edit line is replaced by the next line in history buffer, if the
history stack pointer does not already point to the last entry, and the
cursor is moved to the end of the line. This function is normally assigned to
the 'Arrow down' key.
Previous history line (Ctrl-p/termcap ku)
The current edit line is replaced by the previous line in history buffer, if the
history stack pointer does not already point to the first entry, and the
cursor is moved to the end of the line. This function is normally assigned to
the 'Arrow up' key.
Cursor to start of line (Ctrl-a/termcap kh)
The cursor is moved to the first position of the edit line, if not already
there. The content of the current edit line remains unchanged.
Alternate cursor to start of line (Ctrl-a/termcap ka)
Same as above, intended to allow the use of both cursor key (Home) and, for
example, uEmacs control key.
Cursor to end of line (Ctrl-z/termcap kH)
The cursor is moved past the last position of the edit line, if not already
there. The content of the current edit line remains unchanged.
Alternate cursor to end of line (Ctrl-e/termcap kA)
Same as above, intended to allow the use of both cursor key (End) and, for
example, uEmacs control key.
Clear to end of line (Ctrl-k/termcap kE)
The string from the current cursor position to end of line is deleted and
saved in the paste buffer but not in the history stack. The cursor is not
moved.
Reset terminal (Ctrl-g/termcap kS)
The terminal settings are restored to the condition that was found when 'sh'
was started. This function is intended to cope with a situation when 'sh' has
forked a program that did not restore the terminal settings appropriately.
Delete current line ('del' from terminal path options, kL)
The entire edit string is deleted and saved in the paste buffer but not in
the history stack. The cursor is moved to the leftmost position.
Transpose current and previous character (Ctrl-t/termcap kT)
The two characters, under the cursor and to the left of the cursor, are
exchanged.
Toggle insert/overwrite mode (Ctrl-v/termcap kI)
By default, any character entered from the keyboard is inserted into the
edit line. This command, if used once, changes to overwrite mode, i.e. a
newly entered character replaces the character under the cursor. If used a
second time, the default behavior is restored.
Complete name (Ctrl-i/termcap ta)
The TAB key (or the key specified by the 'ta' termcap entry) causes 'sh' to
match the already entered string as a command, as a file name, as a shell
variable name or as a user name, if it is the first word in a line, it is a
valid file name, its first character is '$' or its first character is '~',
respectively. In case there is more than one match, the terminal beeps and the
user may hit the same key again in which case the entire list of matching
names is displayed. Should more than 100 names match, the user can suppress
the display. If the completed string specifies a file name or a command, a
space is appended. A slash is appended, if it specifies a valid directory.
The name to be completed may contain wild card characters and regular
expressions. If it is not a shell variable, it may also contain shell
variables and the tilde symbol that are both evaluated before completion
takes place. By default, commands are searched in the alias list, in the list
of currently available functions and in the list of built-in commands. The
files in one of the execution directories (any of the PATH directories and
execution directory) may be included into command name completion by a shell
option (-g). Finally, if the first character of an input line is the
exclamation mark ('!') followed by a match string and the completion key is
entered, the most recent history line that matches the string is inserted.
History line completion never reports more than one match, even if there are
less recent entries that also match. As with the normal history syntax, it
is also possible to enter an exclamation mark followed by a number in which
case the history line at this number is inserted. In contrast to the other
completion modes, history line completion is not limited to words - the entire
history line including any white space is inserted.
Clear screen (Ctrl-l/termcap kc)
The screen is cleared, the cursor is moved to the upper left position, and the
current prompt and the current edit line, if any, are written to the first
screen line.
Insert from paste buffer (Ctrl-y/termcap ki)
Any string that has been saved to paste buffer using the "clear to end of
line", "delete current line" or "abandon edit line" command is pasted into the
current edit line.
Abandon edit line (Ctrl-c/termcap kq)
The current edit line is copied into paste buffer but not saved in history
stack, the string "* Abandon *", a carriage return and a new prompt are
written to screen, and the current edit line is cleared.
Reverse-incremental history search (Ctrl-r/termcap kQ)
Every subsequently entered character is appended to a search string that is
looked up in the history lines starting from the most recent entry. Whenever
this line editing command is entered another time, the next less recent
occurrence of the search string in the history lines is displayed on screen.
If a match cannot be found, the terminal beeps and the display does not change.
The reverse-incremental history search can be left using three different ways:
i) If the enter key is hit, the currently selected history line is copied
into the edit command line and the command is executed. ii) If the left-arrow,
right-arrow, begin-of-line, end-of-line or backspace key is hit, the currently
selected history line is copied into the command line, the respective move or
backspace command is applied and edit mode is resumed. iii) If any other
non-alphanumeric key is hit, the search is canceled, the previous edit line is
restored and edit mode is resumed.
Word delete (Esc,d/termcap kX)
The word under the cursor beginning at the current cursor position is copied
into paste buffer and deleted from the current edit line.
Uppercase word (Esc,u/termcap kU)
The characters of the word under the cursor beginning at the current cursor
position are changed to uppercase.
Lowercase word (Esc,l/termcap kY)
The characters of the word under the cursor beginning at the current cursor
position are changed to lowercase.
Capitalize word (Esc,c/termcap kC)
The characters of the word under the cursor beginning at the current cursor
position are changed to lowercase, the first character is made uppercase.
Word forward (Esc,f/termcap kF)
The cursor is moved to the first character of the word that follows the word
under the cursor.
Word backward (Esc,b/termcap kB)
The cursor is moved to the first character of the word that precedes the word
under the cursor.
New line ('eor' from terminal path options)
The edit function is left, the current edit line is sent to the 'sh' input
line parser and the commands, if any, are executed.
Logout ('eof' from terminal path options)
If the '-l' option is not enabled, this character causes 'sh' to execute
'$HOME/.logout' and '/dd/SYS/sh.logout', to stop execution and to return to
the previous program. If history is enabled, the contents of the history
buffer are written to the file '$(HOME)/.sh_history'.
6. General concept of the shell syntax and symbols
------------------------------------------------------
The general concept of the shell syntax is based on simple commands that are
parsed, possibly substituted and, if appropriate, passed to the operating
system. A simple command is a sequence of optional variable assignments
followed by whitespace-separated words and redirections, and terminated by a
control operator. The first word specifies the command to be executed. The
remaining words are passed as arguments to the invoked command. The return
value of a simple command is its exit status. Several simple commands may be
concatenated into a pipe using one of the equivalent pipe symbols
('|' or '!'), and several pipes may be concatenated into a list using one
of the different list symbols (;, &, &&, ||) and terminated by one of the
terminator symbols (;, &, <newline>). Except in the case where a symbol
character is not a legal component of a word such as the '&' symbol, symbols
must be separated with whitespace from words and from each other. This is a
fundamental difference to the concept of many computer languages, in
particular to the C language. A comparable fundamental difference applies to
string elements that must always be marked as such in the C language (using
double-quotes) but do not need to be marked in the the shell language, since
there are only strings anyway. The unspecific use of double-quotes may even
lead to unwanted effects, since they specifically protect a string against
expansion.
6.1. Pipe symbol ('|' or '!')
Any two commands separated by the pipe symbol are started concurrently the
standard output path of the first program being redirected to the standard
input path of the second program via an unnamed pipe.
6.2. Redirection symbols ('<', '>', '2>', '>>', '>+', '>-', '>&', '>&-')
Condensed redirection ('<>', '<>>', '<>>>', '>>>' etc.)
Standard input, standard output and standard error output are redirected
using the '<', '>' and '2>' redirection symbols, respectively. Any existing
file is silently overwritten. The output is appended, if the '>>' symbol
('Bourne mode' only) or the '>+' is used. If in 'Mware mode', the '>>' symbol
redirects standard error path. By default, 'sh' is in 'Bourne mode'; it
is switched to 'Mware mode', if '*' is used as comment symbol in a script. The
'#' comment symbol switches back to 'Bourne mode'. The '>-' symbol is only
implemented for the sake of compatibility with the Mware shell; it is,
however, not different from the '>' symbol. In addition, the outputs from
several paths may be merged together using the '<from>>&<to>' syntax, where
<from> specifies the output path that is going to be closed and be merged into
path <to>. This syntax is, for example, helpful to grep through a program's
error output. The following command will only display those GNU C compiler
options that are related to the '-M' option:
gcc2 -? 2>&1 | grep ' -M'
The order in which redirections are specified is significant. The shell
evaluates redirections left-to-right. For example:
<cmd> 1><file> 2>&1
first associates file descriptor 1 with file <file>. It associates file
descriptor 2 with the file associated with file descriptor 1 (that is, <file>).
If the order of redirections were reversed, file descriptor 2 would be
associated with the terminal (assuming file descriptor 1 had been) and file
descriptor 1 would be associated with file <file>.
If a '-' sign is specified after the merge symbol (&) instead of a path
number, this path is simply closed, e.g. '2>&-' will suppress any output on
standard error path. Finally, the condensed redirection syntax ('<>', '<>>',
'<>>>', '>>>' etc.) is understood, which may be followed by a '+' a '-' symbol
as explained above.
6.3. History symbol ('!', if first character of an input line)
There are several ways to directly execute commands from the history buffer.
The history symbol alone will execute the most recent command; if followed by
a number, the history line with this number is executed. If the history symbol
is followed by a match string, the most recent command that matches this
string is executed. If the completion key is entered at the end of a line
that starts with the history symbol, history completion is attempted, i.e.
the most recent history line that matches or the history line with the
specified line number, if it exists, is inserted into the current edit line.
6.4. Assignment symbol ('=')
A new shell variable is created and a value assigned. The variable 'var' is,
for example, set and defined, if the command
var="sh = flexibility"
is entered. The variable can be recalled when preceded by the '$' sign (see
below). By default, the newly created variable is not exported when a child
process is forked. Another assignment may follow immediately on the same line,
e.g.
abc=123 def=456
In addition, a single assignment or several assignments may be followed by
any legal shell command construct, again on the same line. In this special
case, the variables will be made exportable by default and will be removed
after execution of the command. Any existing environment variable may be
shadowed as demonstrated in the example:
# setenv TERM vt100
# echo $TERM
vt100
# TERM=vt320 printenv TERM
vt320
# echo $TERM
vt100
6.5. Variable symbol ('$')
Any environment variable and shell variable can be recalled when the
variable's name preceded by the '$' sign is entered. The sequence '$<n>'
recalls the arguments of a shell script or variables that have been set using
the 'set' command. The following shell built-in variables are additionally
available:
Symbol Returns
$# the number of arguments (updated)
$* concatenated command line arguments (updated)
"$*" command line arguments concatenated with first
IFS character (updated)
$@ concatenated command line arguments, same as $* (updated)
"$@" command line arguments expanded into separate words
(updated)
$- shell options (updated)
$? value returned by the last command or function executed
$$ the shell's process ID
$<n> the <n>th command line argument, see above (updated)
${~0} same as $$
${~} the shell's parent proces ID
${~1} same as ${~}
${~2} the shell's grandparent process ID
${~<n>} the shell's parent process ID degree <n>
$! the process ID of the most recently invoked concurrent
command
$: the shell's current priority (updated)
$. the shell's current user group number (updated)
$, the shell's current user ID (updated)
$var value of var, empty if var is not defined.
${var} same as above, required if var is followed by a
character that could be part of a variable's name.
${var=new} value of var if defined, 'new' otherwise.
If undefined, $var is set to 'new'.
${var:=new} value of var if defined and not empty, 'new' otherwise.
If undefined, $var is set to 'new'.
${var-new} value of var if defined, 'new' otherwise.
If undefined, $var remains unchanged.
${var:-new} value of var if defined and not empty, 'new' otherwise.
If undefined and not zero, $var remains unchanged.
${var+new} 'new' if var is defined, empty otherwise.
${var:+new} 'new' if var is defined and not empty, empty otherwise.
${var?} value of var if defined, 'var: parameter not set' is
printed otherwise and 'sh' aborts, if interactive.
${var:?} value of var if defined and not empty, 'var: parameter null
or not set' is printed otherwise and 'sh' aborts, if
interactive.
${var?str} value of var if defined, 'var: str' is printed otherwise
and 'sh' aborts, if interactive.
${var:?str} value of var if defined and not empty, 'var: str' is
printed otherwise and 'sh' aborts, if interactive.
There is one specific exception from the rule for shell variable evaluation:
The sequence '$temp$' is always returned unprocessed so that OS-9 V3.0 names
for temporary files ('_$temp$_<xxxx>') can be entered as if there were no '$'
characters (required for execution of 'cfp' generated files).
6.6. Concurrent execution symbol ('&')
A command delimited by the '&' symbol is executed in the background and its
process ID is written to screen. The 'wait' command can be used to abolish
concurrent execution and to wait until the command is finished.
6.7. Sequential execution symbol (';')
Several commands that are separated by the ';' symbol will be executed
sequentially, same as if the commands had been entered separately.
6.8. Evaluation symbol ('`')
Any command or list of commands embedded in backquotes will first be
executed and its output be treated as shell input string. If, for example,
only memory resident RBF disk descriptor modules d0 to d3 and h0 to h3 are
to be saved, the commands
for i in `mdir -ut=desc "??" | grep [dh][0-3]`
do
save $i
done
will do the job.
6.9. Comment ('#' and '*') and execution ('@', '~*' and '*!') symbols
Any line that starts with one of the comment symbols is ignored. There is,
however, one exception from this rule: The first line of a procedure file may
indicate the shell (or any other) program for processing using the '#!<prog>'
syntax. If a fully qualified file name is specified that cannot be found
(e.g. '#!/bin/sh'), its base name ('sh' in the example) is tried. There are
important differences between the two comment symbols: The '#' symbol can
appear at the beginning of a word anywhere in a command line and switches the
I/O syntax parser to 'Bourne mode' so that the '>>' redirection syntax is
recognized as append symbol. The '*' symbol can only appear in procedure files
and only at the beginning of a command (i.e. at the beginning of a line or
following a semicolon) and switches the I/O parser to 'Mware mode' so that the
'>>' syntax is recognized as redirection of standard error path.
In addition, the execution symbol '@' (only if first character of a procedure
file) informs 'sh' that the 'zsh' shell is required, and the character sequence
'~*' (only if first two characters of a procedure file) indicates that this
procedure file requires Mware's command file processor 'cfp' for execution.
Last not least, the character sequence '*!' causes 'sh' to fork the Mware
shell 'mshell' to execute the script file.
6.10. Test symbol ('[')
This symbol is merely a synonym for the 'test' command. In contrast to 'test',
however, end of the test condition may be marked using the ']' character.
6.11. Shell level symbol (@)
This symbol is replaced by the current shell level (stored in the environment
variable _sh).
6.12. Single quote (')
Used to prevent a character, e.g. space, wild card symbol etc., from being
treated by the command line parser. Only the single quote, not the double
quote, also prevents shell variables and backslashes from being evaluated. The
following command allows, for example, to redefine the prompt string:
setenv PS1 '$CWD:'
6.13. Double quote (")
Used to prevent a character, e.g. space, wild card symbol etc., from being
treated by the command line parser. In contrast to single quotes, shell
variables within double quotes are evaluated. The following command will
display all descriptors in memory that have 't' as first character:
mdir -et=desc "t*"
6.14. Mark symbol (<<)
Used to mark an end-of-file string for so-called here documents. Subsequently
entered lines are written to an intermediate file until the mark string is
reached, e.g.:
cat << ENDMARK >textfile
You are reading
the file 'textfile'.
ENDMARK
list textfile
You are reading
the file 'textfile'.
The intermediate file is created on the directory that is specified in the
TMPDIR environment variable or '/dd/TMP', if undefined. It is silently created,
if not yet available. The file name of the temporary file is 'sh' suffixed by
the 6-digit number of the shell's process ID. Any '$', '\' or grave (`...`)
construct in the here document are substituted unless the mark string is
quoted or preceded by a backslash. For example, in the following
cat << ENDMARK >pidprio
This shell's pid is $$ and its priority is $:
ENDMARK
list pidprio
This shell's pid is 000012 and its priority is 128
substitution takes place whereas in
cat << 'ENDMARK' >getpid
The shell's pid can be obtained using the $$ symbol
ENDMARK
list getpid
The shell's pid can be obtained using the $$ symbol
the '$$' symbol or in
cat << \ENDMARK >getprio
The shell's priority can be obtained using the $: symbol
ENDMARK
list getprio
The shell's priority can be obtained using the $: symbol
the '$:' symbol is taken literally.
6.15. Escape character symbol (\)
Used to enter characters that have a special meaning in the 'sh' context and
also non-printable ASCII characters. The following command, for example,
displays all lines of a text file that contain the dollar character at end of
line:
grep \\\$\$ file.c
Note that the four escape characters have different meanings; the first two
encode the escape character itself to be passed to the grep program, the two
others are necessary to enter the dollar character without being treated as
the 'sh' variable denominator. The two dollar characters also have different
meanings; the first one specifies anchored search (only at end of line) and
the second specifies the dollar character to search. When received by the grep
program, the command line arguments will be transformed to
grep \$$ file.c
Another example relates to the conversion of UNIX text files to OS-9. The
following command does appropriate translation of the line-feed (0x0a) line
delimiter to carriage-return (0x0d)
tr \\l \\n <unix >os9
and is functionally equivalent to
tr \\0a \\0d <unix >os9
but could also be written as
tr '\l' '\n' <unix >os9
or as
tr '\0a' '\0d' <unix >os9
The built-in echo command recognizes the following special escape characters:
Symbol Output ASCII Function
\a 0x07 BEL Alert
\b 0x08 BS Backspace
\c Suppress carriage return (same as -r option)
\f 0x0c FF Form feed
\l 0x0a NL New line
\n 0x0d CR Carriage return
\r 0x0d CR Carriage return
\t 0x09 TAB Forward tab
\v 0x0b VT Vertical tab
\\ '\' Backslash
\OOO Any character, if OOO is an octal character that
has a value of less than 256 (octal 377)
\XX Any character, if XX is a hexadecimal character
(upper or lower case)
6.16. Home symbol (~)
The tilde is replaced by the current HOME directory or, if followed by a valid
user name, by this user's home directory. In addition, the tilde and the
following character are replaced by the current working directory, if the tilde
is followed by a '+' sign and by the last working directory, if followed by a
'-' sign, repectively. These mechanisms are also available when the tilde is
the first character of a file name that is subjected to TAB file name
completion.
7. Environment variables
----------------------------
7.1. _sh
This variable contains the shell level, i.e. it can be used to display how
often a child shell has been forked. It cannot be unset.
7.2. EMSG_FILE
The file that may optionally be specified in the EMSG_FILE environment
variable is used for printing error texts, same as '-e[=<path>]' command line
option. In contrast to the command line option, the environment variable
EMSG_FILE must be set before 'sh' is started to become effective. Setting
it to another value within an 'sh' session does not influence the current
error message file. Whenever another error message file is specified using
the 'set -e=<path>' command, the environment variable EMSG_FILE is updated
implicitly. It cannot be unset.
7.3. HISTORY
The value that may optionally be specified in the HISTORY environment variable
defines the size of the history buffer, if set before 'sh' is started. Setting
it to another value within an 'sh' session does not influence the current
history buffer size. Whenever the current history buffer is resized, e.g.
using the 'history <num>' command, HISTORY is updated implicitly.
7.4. TMPDIR
The TMPDIR environment variable is used to store temporary data such as here
documents, default is '/dd/TMP'. If the specified or the default directory
is not available, it is automatically created when needed for the first time.
The environment variable TMPDIR cannot be unset.
7.5. PATH
The colon-separated directories in the PATH environment variable are scanned
whenever the first string of an input line is not a built-in command, is not a
fully qualified file name and does not specify an executable module that is
resident in memory.
When a file is found in one of the PATH directories, an attempt is made to
execute the file; default is '/dd/CMDS', if the PATH variable is empty. The
first file found is executed, irrespective of whether it is a binary program
or a procedure file. In the latter case, the file is, of course, not directly
executed but forked using the shell that is taken from the file (see above)
or, otherwise, that is specified in the SHELL environment variable. If the file
is not found in one of the PATH directories, an attempt is made to execute it
from the current execution directory, but this requires that the file has the
execute attribute set. As above, also a file in the current execution directory
may be either a binary program or a procedure file. The dot ('.') symbol in the
PATH list (e.g. '.:/dd/CMDS') has a special meaning: It always refers to the
current data directory and not to the current execution directory, since the
latter is scanned anyway. The same rule applies to the './' prefix (e.g.
'./procedure') that also refers to the current data directory. The environment
variable PATH cannot be unset.
7.6. HOME
The HOME environment variable is expected to contain the home directory. This
is the directory where the '.profile' file is searched and where the history
file '.sh_history' is saved, if history is enabled. The HOME environment
variable defaults to '/dd'. It cannot be unset.
7.7. CDD
The CDD environment variable contains the disk device of the current data
directory and is automatically updated when a 'chd' command is executed. It
is read-only and cannot be unset.
7.8. CDL
The CDL environment variable contains the lowest level of the current data
directory (not the entire tree) and is automatically updated when a 'chd'
command is executed. Intended to cope with long $CWD strings that are part of
the prompt. The PS1 environment variable can, for example, be set to the
expression
<$HOST/$USER/sh@>$CDD/-/$CDL:
instead of
<$HOST/$USER/sh@>$CWD:
so that the prompt remains reasonably short even when the current directory
points to a deep level in the directory tree. The CDL environment variable is
read-only and cannot be unset.
7.9. CDPATH
The CDPATH environment variable may contain a colon separated list of
directories. These directories are searched when the argument to the
'cd <newdir>' or 'chd <newdir>' built-in command is not found in the current
directory.
7.10. CWD
The CWD environment variable contains the current data directory and is
automatically updated when a 'cd' or a 'chd' command is executed. If the CWD
environment is already set when 'sh' for OS-9 is started, a 'chd $CWD' command
is executed implicitly; it is set to the current directory, otherwise. The
CWD environment variable is read-only and cannot be unset.
7.11. LWD
The LWD environment variable contains the previous current data directory and
is automatically updated when a 'cd' or a 'chd' command is executed.
7.12. TERM
The TERM environment variable is used to select the appropriate termcap
setting. This is the only environment variable that, by default, also acts on
the current 'sh' session. It cannot be unset.
7.13. IFS
The IFS environment variable contains a list of characters that separate words
in arguments. It cannot be unset.
7.14. OLDPWD
The OLDPWD environment variable contains the previous current data directory
and is automatically updated when a 'cd' or a 'chd' command is executed. Its
behavior is identical to the LWD environment variable.
7.15. PPID
The PPID environment variable contains the process ID of the parent process of
the current 'sh'. It is identical to ${~} and ${~1}, is read-only and cannot
be unset.
7.16. PS1
The PS1 environment variable contains the current prompt string, default for
super user login is '@# ', default for any other login is '@% '. It cannot be
unset.
7.17. PS2
The PS2 environment variable contains the prompt string for a continued
command line, e.g. within quotes or within a do loop; default is '> '. It
cannot be unset.
7.18. PS3
The PS3 environment variable contains the prompt string for input as part of
the 'select' language construct; default is '#? '. It cannot be unset.
7.19. PWD
The PWD environment variable contains the current data directory and is
automatically updated when a 'cd' or a 'chd' command is executed. This
functionality is identical to the CWD environment variable. If PWD, however,
is already set when 'sh' for OS-9 is started, it is - in contrast to CWD - not
considered. The PWD environment variable is read-only and cannot be unset.
7.20. SHDEBUG
The SHDEBUG environment variable forces the '-d' (debug) option to be set on
all dependent 'sh' calls. The debug option is disabled when SHDEBUG is either
not set or set to '0', 'OFF' or 'off', it is enabled when set to a non-zero
value, to 'ON' or 'on'. SHDEBUG cannot be unset.
7.21. SH_VERSION
The SH_VERSION environment variable contains the edition number of the
currently running instance of 'sh'. It can neither be unset nor set to another
value. If, for example, a script relies on a particular feature that is only
available from edition 142 onwards, the following command sequence may be
used:
required=142
if test -z $SH_VERSION || test $SH_VERSION -lt $required
then
if test -z $SH_VERSION
then
echo Current shell is too old
else
echo Current shell is edition $SH_VERSION
fi
echo Edition $required required
echo Please upgrade
exit 1
fi
8. Built-in commands
------------------------
8.1. . <file>
Read and execute commands from <file>. This command is similar to the
'profile' command of the Mware shell; if compatibility is an issue, the line
alias profile .
may be added to one of the initialization scripts ('.login', '/dd/SYS/profile'
or '.profile').
8.2. :
Does nothing. A zero exit code is returned.
8.3. [
This command is merely a synonym for 'test'. In contrast to 'test', however,
end of the test condition may be marked using the ']' character.
8.4. alias <new> <old>
This command allows to assign the action <old> to the newly defined string
<new>. The following is an example for useful alias settings that may be put
into the '/dd/SYS/profile' file:
alias a alias
alias chkdsk dcheck
alias env printenv
alias h history
alias last 'chd $LWD'
alias md makdir
alias profile .
alias rm del
alias rmdir deldir
alias sd srcdbg
alias sy sysdbg
alias type list
The command 'alias' without an argument lists the current contents of the
alias buffer on screen.
8.5. break [<level>]
The 'break' command unconditionally stops the execution of a 'for', 'while'
or 'until' loop. Execution is resumed after the end of loop level <level>;
a value of 1 refers to the current loop, 2 refers to to nextmost outer loop
etc. If 'break' is entered without argument, <level> defaults to 1.
8.6. builtin <builtin> [<args>]
Execute the shell built-in command <builtin> passing arguments <args>.
Required, if a function has the name of a built-in command, but the built-in
command needs to be executed within that function.
8.7. cd [<dir>]
Make <dir> the current data directory. The CWD environment variable is also
set to <dir>, the LWD environment variable is set to the most recent data
directory. If 'cd' is entered wihout argument, the user's home directory is
made the current data directory. The command 'cd -' causes the most recent
data directory to become the current directory (same as 'cd $LWD').
8.8. chd [<dir>]
Make <dir> the current data directory. The CWD environment variable is also
set to <dir>, the LWD environment variable is set to the most recent data
directory. If 'chd' is entered wihout argument, the user's home directory is
made the current data directory. The command 'chd -' causes the most recent
data directory to become the current directory (same as 'chd $LWD').
8.9. chx <dir>
Make <dir> the current execution directory.
8.10. cls
Clear screen.
8.11. dirs
Display the current stack of remembered directories. The 'popd' command is
used to recall a particular directory, the 'pushd' command adds a new
directory to the stack or rearranges it.
8.12. continue [<level>]
The 'continue' statement branches to the beginning of a 'for', 'while' or
'until' loop. Execution is resumed at the beginning of loop level <level>;
a value of 1 refers to the current loop, 2 refers to to nextmost outer loop
etc. If 'continue' is entered without argument, <level> defaults to 1.
8.13. echo [-b|-n|-r] <string1> [<string2> ... <stringn>]
Prints the strings to screen. Optionally carriage return is omitted (-r), one
carriage return is printed after every single string (-n), or backslash
processing of the string is disabled (-b). The latter is, for example, helpful
to display the current setting of the TERMCAP environment variable that
normally contains backslash characters.
8.14. enable [-n] [<builtin>]
This command allows to enable or to disable (-n) a shell built-in command so
that a disk command with the same name can be executed. If 'enable' is entered
without arguments, all shell built-in commands are displayed on screen
preceded by a '+' or a '-' sign, if the particular command is enabled or
disabled, respectively.
8.15. eval <cmd>
Evaluate a command and add the result to the shell's internal variable set;
useful to manipulate environment variables.
8.16. ex <cmd>
Execute command <cmd> and leave the current shell.
8.17. exec <cmd>
Same as ex (see above).
8.18. exit [<code>]
Stop execution of 'sh' and return to the previous program. The return value
may be specified explicitly in the <code> argument; it defaults to zero,
otherwise.
8.19. export <name1>[=<value1>] [<name2>=[<value2>] ... <namen>=[<valuen>]]
The specified names are registered for automatic export to the environment of
subsequently executed commands. A list of all exported variables is produced
when 'export' is entered without arguments. In addition, a new value may be
assigned to the variable, if immediately followed by an equal sign and a
value, e.g.
export NEWENV=newval
8.20. false
Returns the boolean value false for condition constructs such as 'while' or
'if'.
8.21. history [<num>|read|save]
Display the current content of the history buffer, if <num> is not given;
set the length of the history buffer to <num> lines, otherwise. The contents
of the history buffer are written to the file '$HOME/.sh_history' when 'sh'
quits. They are read during initialisation of a login shell, but can also be
re-read later by using the 'history read' command. When 'history save' is
entered, the currents contents of the history buffer are written to
'/$HOME/.sh_history' in the same way as when 'sh' quits.
8.22. kill [-<signal>] [-signal=<signal>] <proc1> [<proc2 ... <procn>]
Send signal <signal> (default 0) to the process or processes specified as
arguments. The argument may be given as process ID or as module name of the
requested process. If the name specifies a module that runs more than once, a
message a displayed and the user is given the choice to kill all or none of
the processes. Note that the kill signal (signal 0) cannot be caught nor
ignored.
8.23. logon
Invoke a new logon procedure, pass the current environment and abandon the
current process. In a first attempt, the program 'logon' is executed; if this
fails, 'login' is tried.
8.24. logout [nohist]
Execute '$HOME/.logout' and '/dd/SYS/sh.logout', stop execution of 'sh' and
return to the previous program. If history is enabled and the optional
'nohist' argument is not specified, the contents of the history buffer are
written to the file '$(HOME)/.sh_history'. If the '-l' option is not
enabled, entering the end-of-file character from the terminal path options
(normally escape) also causes 'sh' to logout.
8.25. NO
This command is only effective, if followed by 'CARRIER' in which case the
entire command is synonymous to 'logout'. Intended to correctly handle a
situation when the carrier is lost in a modem connection but the serial
interface is not able to detect changes in the DCD line.
8.26. pd [-x]
Display current data directory; the current execution directory is shown
instead, if the '-x' option is specified. Same as 'pwd'.
8.27. popd [+n]
Removes the entry n from the directory stack. If 'popd' is entered wihout
argument, the top directory is removed from the stack and made the current
data directory.
8.28. printenv [<var1> <var2> ... <varn>]
Print all (exportable ) environment variables. This command also excepts a
single argument or several ones that are output, one per line, in the
specified order. Unavailable variables are silently ignored.
8.29. pushd [dir] | [+n]
Adds a directory to the top of the directory stack, if [dir] is a valid
directory; otherwise, the directory stack is rotated until the nth element of
the directory stack is at top. If 'pushd' is entered without argument, the top
two directories are exchanged. After the rearrangement of the stack, the top
directory is always made the current data directory.
8.30. pwd [-x]
Display current data directory; the current execution directory is shown
instead, if the '-x' option is specified. Same as 'pd'.
8.31. read <var1> [<var2> ... <varn>]
The 'read' command reads a string that is entered at the keyboard into a
single variable or into several variables. If a single variable is specified,
whitespace is maintained; if several variables are specified, whitespace is
ignored and the separated input tokens are assigned to the variables in the
given order. The read command returns 0 in case of no error; it returns 1,
if end-of-file (normally Escape) is received. A value of 2 or 3 is returned,
if keyboard quit or keyboard abort was entered, respectively. Should a signal
be received during the read command, the number of the signal is returned.
If the '-l' option is set, end-of-file can be entered by hitting the
end-of-file character twice. The read command is the only shell built-in that
is able to receive input from a pipe, e.g.
procs -e | grep myprog | read id pid grpusr prio memsiz
This makes it possible to easily realize a simple string parser.
8.32. readonly <name1>[=<value1>] [<name2>=[<value2>] ... <namen>=[<valuen>]]
Make the variable specified as argument read-only. Any shell variable
including environment variables can be passed as argument. If, for example,
the TERM variable is intended to be protected against unintentional changes,
the command
readonly TERM
can be used. Any attempt to assign another value to the TERM environment
variable will then result in an error message. In addition, a new value may be
assigned to the variable, if immediately followed by an equal sign and a
value, e.g.
readonly PROTECTVAL=safe
8.33. return [<val>]
A function exits and, optionally, returns the value <val>.
8.34. set <var1> [<var2> ... <varn>]
This command is used to set shell command arguments in the same way, as if they
had been entered when starting the shell. This includes options and other
arguments, but they cannot be mixed. If the first argument to the 'set'
command starts with the '-' character, all following strings are considered
options; they are taken as arguments, otherwise. To inhibit the login
procedure when the escape character is entered, the command
set -l
can, for example, be used. If 'set' is entered without arguments, a list of
all currently defined environment variables, shell variables and functions is
produced. Finally, 'set -' can be entered in which case all flags except the
'-l' flag will be set to their defaults.
8.35. setenv <variable> <value>
Define the environment <variable> and assign <value> to it. In contrast to the
assignment command '<variable>=<value>', the 'setenv' command implicitly sets
the variable attribute to 'export' so that it is automatically exported when a
child process is forked.
8.36. setpr [<pid> <priority>] [<priority>]
Set the priority of the process with the process ID <pid> to <priority>.
Alternatively, the default priority for future forks can be set. If 'setpr' is
entered without arguments, the current default process priority is displayed
on screen.
8.37. setstack [<stack>]
Set the additional data stack to <stack> kByte when forking a program. If
'setstack' is entered without arguments, the current additional data stack
size is displayed on screen.
8.38. setuid <group.user> | <name>
Set the shell's group and user ID; can only be executed, if the shell process
is owned by a member of the super user group.
8.39. shift <n>
The positional parameters from <n+1> etc. are renamed to $1 etc. If <n> is not
given, 1 is assumed. The 'shift' command is useful for command line parsing.
8.40. show
All shell variables including environment variables are displayed on screen.
8.41. suspend [<signal>]
The shell is suspended until the signal <signal> is received. Any activity is
suspended except that traps for other signals (installed using the 'trap
<command> <number>' command) are executed. If <signal> is not specified, any
signal will restart the shell.
8.42. test <opt1> <arg1> <opt2> [<arg2>]
The 'test' command is used to perform a number of unary tests and binary
comparisons; it returns true, if one of the following options is specified
and the respective condition is true:
Paths, descriptors and modules:
-b arg1 is a block device descriptor (RBF/NFS, SBF, CDFM)
-d arg1 is an existing path and is a directory
-f arg1 is an existing path
-h always returns false (Unix: <arg1> is a symbolic link)
-L always returns false (Unix: <arg1> is a symbolic link)
-m arg1 is an existing memory module
-p arg1 is an existing path and is a named pipe
-r arg1 is an existing path and is readable
-s arg1 is an existing path and has a size greater than zero
-t arg1 is an existing path open to a terminal
-w arg1 is an existing path and is writable
-x arg1 is an existing path and is an executable file
Strings:
-z arg1 is an empty string
-n arg1 is a non-empty string
<arg1> = <arg2> true if string <arg1> equals string <arg2>
<arg1> != <arg2> true if string <arg1> is not equal string <arg2>
Integers:
-eq true if integer <arg1> equals integer <arg2>
-ne true if integer <arg1> is not equal integer <arg2>
-ge true if integer <arg1> is greater than or equal <arg2>
-gt true if integer <arg1> is greater than integer <arg2>
-le true if integer <arg1> is lower than or equal <arg2>
-lt true if integer <arg1> is lower than integer <arg2>
Expressions:
!<arg> true if <arg> is false
-a true if both <arg1> and <arg2> are true
-o true if either <arg1> or <arg2> is true
Several logical conditions can be grouped together using parentheses. The
following condition, for example, would return true, if only 'file1' exists
if test -f file1 -o ( -f file2 -a -f file3 )
while
if test ( -f file1 -o -f file2 ) -a -f file3
would return false in such case. The first example could also have been written
without parentheses.
8.43. trap [<command> <number>]
Define an action to be executed when signal <number> is received; the command
trap "echo 'You better NOT kill your shell...'" 2
will, for example, display the string 'You better NOT kill your shell...' when
Cntrl-E is entered from the keyboard. A trap can be removed from a signal by
entering 'trap' followed just by that signal number. If 'trap' is entered
without arguments, a list of all currently trapped signals is produced.
8.44. true
Returns the boolean value true for condition constructs such as 'while' or
'if'.
8.45. tty [<devno>]
Return the name of the path number <devno>. If not specified, <devno> defaults
to 0.
8.46. umask [<mask> | <attr>]
Return the current file creation mode mask for files created by 'sh', if
entered without arguments (default modes are owner read and owner write). A
new file creation mode mask may be entered using the octal number <mask>; bits
that are set in the mask are cleared in the modes of created files.
Alternatively, new file modes may be entered as they were arguments to the
OS-9 utility 'attr'. Only owner read/write and public read/write modes can be
set or cleared.
8.47. unalias <alias>
Undefine the string previously assigned to <alias>.
8.48. unset [-f] <function> | <variable>
Make a previously defined function ('-f' option) undefined. If the '-f' option
is not specified, 'unset' is identical to 'unsetenv' except that no error is
generated, if an attempt is made to unset a non-existing variable.
8.49. unsetenv <variable>
Make a previously defined environment or shell variable undefined.
8.50. version [<help>]
Display 'sh' version, edition and compilation date. The argument <help> may be
any of 'c(ommands)', 'k(eycaps)', 'l(anguage)', or 't(est)' to display a
listing of available shell built-in commands, keycap settings, language
construct elements, or test functions, respectively. A '+' or '-' sign that
precedes the name of a shell built-in command indicates whether that particular
command is currently enabled or not.
8.51. w
Suspend 'sh' until any one child process terminates and return its termination
status.
8.52. wait [<pid>]
Suspend 'sh' until the process with process ID <pid> has finished and return
its termination status. If no argument is specified, 'sh' waits until all
child processes have finished, in which case the return value is always zero.
9. Language construct elements
----------------------------------
9.1. for <var> [in <val1> <val2> ... <valn>]
The 'for' construct is used to execute loops in shell scripts; every time
the subsequent do .. done segment is executed, <var> will be set to <val1>,
<val2>, until <valn> is reached. If, for example, library files have to be
scanned for the occurrence of a specific function, the commands
for i in /h0/LIB/*.l
do
echo Scanning $i:
rdump $i -a | grep function
done
may be entered. Shell arguments are used as variable values, if the 'in'
language construct element is omitted.
9.2. select <var> [in <val1> <val2> ... <valn>]
The 'select' construct is intended to let the user select from a list of
values; every value is labeled by a consecutive number starting from 1. The
selected item is assigned to <var> during execution of the subsequent do ..
done segment until a 'break' command is encountered or until the user has
entered EOF condition. An empty string is assigned to <var>, if an invalid
selection is made. The string contained in the environment variable PS3 is
displayed after the variable list. The following example lets the user select
a directory from the PATH environment variable:
PS3='Execution directory? '
select dir in `echo $PATH | tr ':' ' '`
do
if [ $dir ]
then
echo You selected directory $dir
break
fi
done
It will, for example, ask for a selection
1) .
2) /dd/USR/CMDS
3) /dd/ETC/CMDS
4) /dd/CMDS
Execution directory?
and, if '2' is entered, display
You selected directory /dd/USR/CMDS
9.3. while [!] <condition>
The do .. done segment that follows the 'while' language construct element
is executed repeatedly, until <condition> becomes false. Optionally,
<condition> may be preceded by the '!' operator in which case the sense of
<condition> is inverted. A program will, for example, rerun continuously,
if the commands
while true
do
program
done
are entered. Such a command sequence may be useful to exhibit software at a
fair.
9.4. case <var> in
The 'case' construct is used to select among several conditions. A simple
user interface to delete or not a particular file in the current data
directory can, for example, be written as
for i in *
do
echo Delete file $i?
read response
case $response in
y*) del $i ;;
n*) ;;
q*) break
esac
done
The match condition may contain the '|' (or) symbol to indicate that several
conditions may match, e.g. 'y*|Y*)'.
9.5. esac
The 'esac' language construct element is a component of the 'case' construct,
see above.
9.6. do
The 'do' construct is a component of the 'for', 'select', 'until' and 'while'
constructs, see above and below.
9.7. done
The 'done' language construct element is a component of the 'for', 'select',
'until' and 'while' constructs, see above and below.
9.8. if [!] <condition>
The 'if' construct is used to execute one or several shell commands based upon
the return value of <condition>. Optionally, <condition> may be preceded by
the '!' operator in which case the sense of <condition> is inverted. Standard
evaluation programs such as 'cmp', 'diff' or 'grep' normally return 0 or 1, if
the program's action fails or not, respectively. The following shell script
can, for example, be used to copy only those files from /h0/CMDS to
/h0/DISK1/CMDS that already exist on /h0/DISK1/CMDS but are different.
cd /h0/DISK1/CMDS
dir=/h0/CMDS
for i in *
do
if cmp $dir/$i $i -u
then
echo $dir/$i is the same as $i
else
echo $dir/$i is DIFFERENT from $i
copy $dir/$i -rb=64
echo $dir/$i copied to $i
fi
done
9.9. in
The 'in' language construct element may optionally be used as part of the
'for' loop, see above.
9.10. then
The 'then' language construct element is a required component of the 'if'
and the 'elif' statements, see above.
9.11. else
The 'else' language construct element may optionally be used within the 'if'
construct, see above.
9.12. elif [!] <condition>
The 'elif' language construct element stands for 'else if' and may optionally
be used within the 'if' construct, see above. Optionally, <condition> may be
preceded by the '!' operator in which case the sense of <condition> is
inverted.
9.13. until [!] <condition>
The do .. done segment that follows the 'until' language construct element
is executed repeatedly, as long as <condition> is false. Optionally,
<condition> may be preceded by the '!' operator in which case the sense of
<condition> is inverted.
9.14. fi
The 'fi' language construct element terminates 'if' and 'elif' constructs, see
above.
9.15. ;;
The ';;' language construct element terminates a selection as part of the case
construct, see above.
9.16. <condition> || [!] <condition>
OR operator for condition constructs following 'if', 'elif', 'while' and
'until'. Optionally, <condition> may be preceded by the '!' operator in which
case the sense of <condition> is inverted. In addition, the OR operator may be
placed between two commands; the second command is then only executed, if the
first one returns false:
false || echo second command is being executed
true || # NEVER REACHED
9.17. <condition> && [!] <condition>
AND operator for condition constructs following 'if', 'elif', 'while' and
'until'. Optionally, <condition> may be preceded by the '!' operator in which
case the sense of <condition> is inverted. In addition, the AND operator may
be placed between two commands; the second command is then only executed, if
the first one returns true:
true && echo second command is being executed
false && # NEVER REACHED
9.18 (
Start an independent subshell to execute the commands in parentheses. The
return value is that of the last executed command:
echo main shell is shell number $_sh
(echo subshell is shell number '$_sh')
9.19. )
Selects a condition within a case statement. The condition may contain the
'*' wildcard character; in addition, the '|' character may be used to indicate
that one of several conditions may match.
9.20. <name> () { <command1> [<command2>] .. [<commandn>] }
Define the shell function <name>. Any commands that may legally be typed from
shell prompt may also appear within a command. End of function is assumed and
the function is internally stored and assigned to <name>, when the '}'
character is reached. The function can be executed just by entering its name;
it may be inspected by using the 'set' command without arguments. Any number
of arguments may be passed to the function; they are recalled within the
function using the '$<n>' syntax. A function may return a value using the
'return <val>' syntax. The return value may be inspected using the '$?' syntax
or directly examined in a 'test' statement. Recursive calls to a function are
allowed. An example for a shell function is given in section 10.4.
9.21. !
The '!' language construct element stands for 'not' and may appear after 'if',
'elif', 'while', 'until', '||' or '&&'. It inverts the return value of the
subsequent logical condition.
10. Constants
----------------
10.1. Input buffer from command line
Initial buffer size is 2048 characters, it is expanded dynamically until the
system's memory is exhausted.
10.2. Input buffer from shell script
Initial buffer size is 2048 characters, it is expanded dynamically until the
system's memory is exhausted.
10.3. Input buffer of built-in read command
Initial buffer size of the input line during the built-in read command is
2048 characters, it is expanded dynamically until the system's memory is
exhausted.
10.4. Input buffer for a syntactical element
Initial buffer size for a syntactical element (command, function, alias etc.)
is 507 characters, it is expanded dynamically until the system's memory is
exhausted.
10.5. Maximum nesting depth
Commands may not be nested more deeply than 8 levels.
10.6. Maximum number of history lines
The number of history lines is limited to 500.
10.7. Maximum length of history match string
The string length of a history match string may not exceed 127 characters.
10.8. Maximum number of aliases
The number of aliases is limited to 100.
10.9. Maximum length of alias string
The string length of an alias string may not exceed 127 characters.
10.10. Default pipe length
Pipes for the communication between concurrently executing programs have a
default length of 512 Bytes. If the output of a shell built-in command is
redirected into a pipe, its size is set dynamically.
10.11. Signal numbers that may be trapped
Only signals with a number between #1 and #63 may be trapped.
10.12. Size of paste buffer
The internal paste buffer ("Clear to end of line", "Delete current line",
"Abandon edit line", "Word delete") has a size of 255 characters.
10.13. Signals
Whenever 'sh' receives signal #4 (SIGHUP), signal #10 (former SIGTERM) or
signal #36 (SIGTERM) and the signal's default action has not been disabled
using the 'trap' command, 'sh' immediately stops execution and returns the
respective signal number.
11. Important features
-------------------------
11.1. Name completion
The TAB key (or the key specified by the 'ta' termcap entry) causes 'sh' to
match the already entered string as a command (command name completion), as a
file or directory name (file name completion), as a shell variable (variable
name completion) or as a user (user name completion). If, for example, the
name of the first of the two files
thisfilehasaverylongname1
thisfilehasaverylongname2
in the current directory is required, is it sufficient to enter
t<TAB>1
If the completion key is entered twice
t<TAB><TAB>
thisfilehasaverylongname1 thisfilehasaverylongname2
t
a list of all available files is displayed on screen and the original input
line repeated below this list so that editing can be continued immediately.
11.2. Regular expressions
Regular expressions are evaluated whenever a string is entered. If, for
example, all files that have 'a', 'b', or 'c' as first character are to be
deleted, the command
del [abc]*
will do the job. Alternatively, the command
del [a-c]*
can be entered for this purpose. The regular expression is also considered
for file name completion. If the first character after the '[' symbol is the
exclamation mark ('!') or the caret symbol ('^'), the sense of the comparison
is inverted, i.e. only strings that do NOT match the character class are
considered.
11.3. Availability of environment variables
All environment variables are available in a command when preceded by the '$'
sign. Inspecting the current setting of the TERM environment variable is, for
example, done by entering the
echo $TERM
command; adding the directory '/h0/BIN' to the PATH environment variable can
simply be done by entering the
setenv PATH $PATH:/h0/BIN
command.
11.4. Shell functions
Shell functions can easily be created and executed. This can be done from
prompt level but functions may also be part of an 'sh' script. Programming
an 'sh' script that makes use of functions is somewhat similar to writing a
program in the C language. Any number of arguments may be passed to the
function; they are recalled within the function using the '$<n>' syntax. The
following 'sh' script may serve as an example:
func1() {
echo Executing function 1.
if [ $4 ]
then
echo $1 $2 $3 $4.
return 0
fi
return 1
}
func2() {
echo Executing function 2.
if [ $4 ]
then
echo $1 $2 $3 $4.
return 0
fi
return 2
}
if test $# -eq 0
then
echo "Please use one of 'f1' or 'f2' as first argument." 1>&2
echo "Optionally, a second argument can be specified." 1>&2
exit 1
fi
if test $1 = "f1"
then
if func1 Command line argument $2
then
echo Arguments printed.
else
echo Function $? executed.
fi
exit 0
fi
if test $1 = "f2"
then
if func2 Command line argument $2
then
echo Arguments printed.
else
echo Function $? executed.
fi
exit 0
fi
echo Illegal argument \'"$1"\' 1>&2
exit 1
12. Compatibility between 'sh' and 'shell'
---------------------------------------------
All main syntax elements are compatible between 'sh' and 'shell'. There are
only a few remaining differences.
12.1. Redirected output overwrites file
In contrast to the Mware shell, 'sh' overwrites files to which output
is redirected. The behavior of the Mware shell can, however, be
simulated by specifying the '-C' command line option.
12.2. Handling of unmatched wildcards
'sh' passes wildcard symbols to the called program, if they do not
match. The Mware shell writes the message "Wildcard match failed
for command '<cmd>'" in such a case and does not call the program.
12.3. Built-in command 'set' requires a hyphen for option setting
Hyphens cannot be omitted when specifying options in the 'set' command,
since 'sh' uses the hyphen to distinguish options from arguments.
12.4. Search order for programs and scripts
Both Mware shells 'shell' and 'mshell' search the current execution
directory prior to the directories specified in the PATH environment
variable, whereas 'sh' uses a more flexible approach and first examines
the PATH variables and then the current execution directory. Mware's
search order may be forced by specifying the current execution
directory as the first element in the PATH environment variable.
13. To do
------------
13.1. TAB name completion and cursor position
TAB name completion only works, if the cursor is at the end of the
input line.
13.2. Interrupting execution of '.' command
When keyboard interrupt or keyboard abort is hit during execution of
a script in the current sh environment (. <file>) sh exits. Would be
preferable, if only execution of the script were stopped.
14. References
-----------------
14.1. Kernighan BW, Pike R (1984): The UNIX programming environment.
Prentice-Hall, Englewood Cliffs, NY. ISBN 0-13-937699-2.
14.2. Bourne SR (1987): The UNIX System V environment.
Addison-Wesley, Reading, MA. ISBN 0-201-18484-2.
14.3. Newham C, Rosenblatt B (1995): Learning the bash shell.
O'Reilly, Sebastopol, CA. ISBN 1-56592-147-X.