summaryrefslogtreecommitdiff
path: root/man/1/sh
diff options
context:
space:
mode:
Diffstat (limited to 'man/1/sh')
-rw-r--r--man/1/sh939
1 files changed, 939 insertions, 0 deletions
diff --git a/man/1/sh b/man/1/sh
new file mode 100644
index 00000000..951f168a
--- /dev/null
+++ b/man/1/sh
@@ -0,0 +1,939 @@
+.TH SH 1
+.SH NAME
+sh, builtin, exit, load, loaded, local, whatis, quote, run, set, unload, unquote \- command language
+.SH SYNOPSIS
+.B sh
+[
+.B -ilxvn
+]
+[
+.B -c command
+]
+[
+.I file
+[
+.I arg ...
+]
+.SH DESCRIPTION
+.I Sh
+is a programmable user level interface (a shell) for Inferno.
+It executes command lines read from a terminal or a file or, with the
+.B -c
+flag, from
+.IR sh 's
+argument list. It can also be used to give programmable functionality
+to Limbo modules (see
+.IR sh "" "" (2)).
+.SS Command Lines
+A command line is a sequence of commands, separated by ampersands or semicolons
+.RB ( &
+or
+.BR ; ),
+terminated by a newline.
+The commands are executed in sequence
+from left to right.
+.I Sh
+does not wait for a command followed by
+.B &
+to finish executing before starting
+the following command.
+Whenever a command followed by
+.B &
+is executed, its process id is assigned to the
+.I sh
+variable
+.BR $apid .
+Whenever a command
+.I not
+followed by
+.B &
+exits or is terminated, the
+.I sh
+variable
+.B $status
+gets the process's wait message (see
+.IR prog (3));
+it will be the null string if the command was successful.
+.PP
+A number-sign
+.RB ( # )
+and any following characters up to (but not including) the next newline
+are ignored, except in quotation marks.
+.SS Simple Commands
+A simple command is a sequence of arguments interspersed with I/O redirections.
+If the first argument is the name of a
+.I sh
+builtin or it is a braced command block (see
+.IR "Compound Commands",
+below), it is executed by
+.IR sh .
+If the first character of the name is a brace
+.RB ( { ),
+the shell tries to parse it and execute it as a braced command block;
+if the parsing fails, an exception is raised.
+Otherwise
+.I sh
+looks for an external program to execute.
+.PP
+If the name ends in
+.BR .dis ,
+.I sh
+looks for a Dis module of that name; otherwise
+it tries first to find a Dis module of
+that name with
+.B .dis
+appended and failing that, it looks for
+an executable file of the same name, which should
+be a readable, executable script file.
+If the name does not start with a slash
+.RB ( / )
+or dot-slash
+.RB ( ./ ),
+then the name is first looked for relative to
+.BR /dis ,
+and then relative to the current directory.
+A Dis module will be executed only if it
+implements the
+.B Command
+interface (see
+.IR sh (1));
+a script file will be executed only if it
+starts with the characters
+.RB `` #! ''
+followed by the name of a file executable
+under the rules above. In this case the
+command will be executed with any following arguments mentioned
+in the
+.B #!
+header, followed by the path of the script file,
+followed by any arguments originally given to the command.
+.PP
+For example, to execute the simple command
+.BR "ls" ,
+.I sh
+will look for one of the following things, in order,
+stopping the search when one is found:
+.RS
+.IP 1)
+a built-in command named
+.RB `` ls ''.
+.IP 2)
+a Dis module named
+.RB `` /dis/ls.dis '',
+.IP 3)
+an executable script file named
+.RB `` /dis/ls '',
+.IP 4)
+a Dis module named
+.RB `` ./ls.dis '',
+.IP 5)
+an executable script file named
+.RB `` ./ls ''.
+.RE
+.SS Arguments and Variables
+A number of constructions may be used where
+.I sh's
+syntax requires an argument to appear.
+In many cases a construction's
+value will be a list of arguments rather than a single string.
+.PP
+The simplest kind of argument is the unquoted word:
+a sequence of one or more characters none of which is a blank, tab,
+newline, or any of the following:
+.EX
+ # ; & | ^ $ ` ' { } ( ) < > " =
+.EE
+An unquoted word that contains any of the characters
+.B *
+.B ?
+.B [
+is a pattern for matching against file names.
+The character
+.B *
+matches any sequence of characters,
+.B ?
+matches any single character, and
+.BI [ class ]
+matches any character in the
+.IR class .
+If the first character of
+.I class
+is
+.BR ^ ,
+the class is complemented. (As this character
+is special to the shell, it may only be included in a pattern
+if this character is quoted, as long as the leading
+.B [
+is not quoted).
+The
+.I class
+may also contain pairs of characters separated by
+.BR - ,
+standing for all characters lexically between the two.
+The character
+.B /
+must appear explicitly in a pattern.
+A pattern is replaced by a list of arguments, one for each path name matched,
+except that a pattern matching no names is not replaced by the empty list,
+but rather stands for itself.
+Pattern matching is done after all other
+operations.
+Thus,
+.EX
+ x=/tmp; echo $x^/*.b
+.EE
+matches
+.BR /tmp/*.b ,
+rather than matching
+.B "/*.b
+and then prefixing
+.BR /tmp .
+.PP
+A quoted word is a sequence of characters surrounded by single quotes
+.RB ( ' ).
+A single quote is represented in a quoted word by a pair of quotes
+.RB ( '' ).
+.PP
+.ne 3
+Each of the following is an argument.
+.PD 0
+.HP
+.BI ( arguments )
+.br
+The value of a sequence of arguments enclosed in parentheses is
+a list comprising the members of each element of the sequence.
+Argument lists have no recursive structure, although their syntax may
+suggest it.
+The following are entirely equivalent:
+.EX
+ echo hi there everybody
+ ((echo) (hi there) everybody)
+ echo (hi
+ there
+ everybody
+ )
+.EE
+Newlines within parentheses count as simple white space;
+they do not terminate the command. This can be useful to give
+some more freedom of layout to commands that take several
+commands as arguments, for instance several of the commands
+defined in
+.IR sh-std (1).
+.HP
+.BI $ argument
+.br
+The
+.I argument
+after the
+.B $
+is the name of a variable whose value is substituted.
+Multiple levels
+of indirection are possible.
+Variable values
+are lists of strings.
+If
+.I argument
+is a number
+.IR n ,
+the value is the
+.IR n th
+element of
+.BR $* ,
+unless
+.B $*
+doesn't have
+.I n
+elements, in which case the value is empty.
+Assignments to variables are described under
+.I "Assignment" ,
+below.
+.HP
+.BI $# argument
+.br
+The value is the number of elements in the named variable.
+A variable
+never assigned a value has zero elements.
+.HP
+\f5$"\fP\fIargument\fP
+.br
+The value is a single string containing the components of the named variable
+separated by spaces. A variable with zero elements yields the empty string.
+.HP
+.BI `{ command }
+.HP
+.I
+\f5"{\fPcommand\f5}\fP
+.br
+.I Sh
+executes the
+.I command
+and reads its standard output. If backquote
+.RB ( ` )
+is used, it is split into a list of arguments,
+using characters in
+.B $ifs
+as separators.
+If
+.B $ifs
+is not otherwise set, its value is
+.BR "'\ \et\en'" .
+If doublequote (\f5"\fP)
+is used, no tokenization takes place.
+.HP
+.IB argument ^ argument
+.br
+The
+.B ^
+operator concatenates its two operands.
+If the two operands
+have the same number of components, they are concatenated pairwise.
+If not,
+then one operand must have one component, and the other must be non-empty,
+and concatenation is distributive.
+.HP
+.BI ${ command }
+.br
+.I Command
+must be a simple command with no redirections;
+its first word
+must be the name of a builtin substitution operator.
+The operator is invoked and its value substituted.
+See
+.IR "Built-in Commands" ,
+below, for more information on builtins.
+.PD
+.SS Free Carets
+In most circumstances,
+.I sh
+will insert the
+.B ^
+operator automatically between words that are not separated by white space.
+Whenever one of
+.B $
+.B '
+.B `
+follows a quoted or unquoted word or an unquoted word follows a quoted word
+with no intervening blanks or tabs,
+a
+.B ^
+is inserted between the two.
+If an unquoted word immediately follows a
+.BR $
+and contains a character other than an alphanumeric, underscore,
+or
+.BR * ,
+a
+.B ^
+is inserted before the first such character.
+Thus
+.IP
+.B limbo -$flags $stem.b
+.LP
+is equivalent to
+.IP
+.B limbo -^$flags $stem^.b
+.SS Assignment
+A command of the form
+.IB name = value
+or
+.IB name := value
+assigns
+.I value
+to the environment variable named
+.IR name .
+.I Value
+is either a list of arguments or an assignment statement. In
+the latter case
+.I value
+is taken from the value assigned in the assignment statement.
+If
+.B :=
+is used, the value is stored in the innermost local scope.
+A local scope is created every time a braced block is entered,
+and destroyed when the block is left. If
+.B =
+is used, the value is stored in the innermost scope
+that contains any definition of
+.IR name .
+.PP
+A list of names can also be used in place of
+.IR name ,
+which causes each element of
+.I value
+in turn to be assigned the respective variable name in
+the list. The last variable in the list is assigned any elements
+that are left over. If there are more variable names than
+elements in
+.IR value ,
+the remaining elements are assigned the null list.
+For instance, after the assignment:
+.EX
+ (a b c) = one two three four five
+.EE
+.B $a
+is
+.BR one ,
+.B $b
+is
+.BR two ,
+and
+.B $c
+contains the remaining three elements
+.BR "(three four five)" .
+.SS I/O Redirections
+The sequence
+.BI > file
+redirects the standard output file (file descriptor 1, normally the
+terminal) to the named
+.IR file ;
+.BI >> file
+appends standard output to the file.
+The standard input file (file descriptor 0, also normally the terminal)
+may be redirected from a file by the sequence
+.BI < file \f1,
+or by the sequence
+.BI <> file \f1,
+which opens the file for writing as well as reading.
+.PP
+Redirections may be applied to a file-descriptor other than standard input
+or output by qualifying the redirection operator
+with a number in square brackets.
+For example, the diagnostic output (file descriptor 2)
+may be redirected by writing
+.BR "limbo junk.b >[2] junk" .
+.PP
+A file descriptor may be redirected to an already open descriptor by writing
+.BI >[ fd0 = fd1 ]
+or
+.BI <[ fd0 = fd1 ]\f1.
+.I Fd1
+is a previously opened file descriptor and
+.I fd0
+becomes a new copy (in the sense of
+.IR sys-dup (2))
+of it.
+.PP
+Redirections are executed from left to right.
+Therefore,
+.B limbo junk.b >/dev/null >[2=1]
+and
+.B limbo junk.b >[2=1] >/dev/null
+have different effects: the first puts standard output in
+.BR /dev/null
+and then puts diagnostic output in the same place, where the second
+directs diagnostic output to the terminal and sends standard output to
+.BR /dev/null .
+.SS Compound Commands
+A pair of commands separated by a pipe operator
+.RB ( | )
+is a command.
+The standard output of the left command is sent through a pipe
+to the standard input of the right command.
+The pipe operator may be decorated
+to use different file descriptors.
+.BI |[ fd ]
+connects the output end of the pipe to file descriptor
+.I fd
+rather than 1.
+.BI |[ fd0 = fd1 ]
+connects output to
+.I fd1
+of the left command and input to
+.I fd0
+of the right command.
+.PP
+A sequence of commands separated by
+.BR & ,
+.BR ; ,
+or newline
+may be grouped by surrounding
+them with braces
+.RB ( {} ),
+elsewhere referred to as a
+.IR "braced block" .
+A braced block may be used anywhere that a simple word
+is expected. If a simple command is found with
+a braced block as its first word, the
+variable
+.B $*
+is set to any following arguments,
+.B $0
+is set to the block itself, and the commands
+are executed in sequence. If a braced block
+is passed as an argument, no execution takes place:
+the block is converted to a functionally equivalent
+string, suitable for later re-interpretation by the shell.
+The null command
+.RB ( {} )
+has no effect and always gives a nil status. For instance
+the following commands all produce the same result:
+.EX
+ echo hello world
+ {echo hello world}
+ '{echo hello world}'
+ {echo $*} hello world
+ sh -c {echo hello world}
+ {$*} {echo hello world}
+ {$*} {{$*} {echo hello world}}
+ "{echo {echo hello world}}
+ '{echo hello' ^ ' world}'
+ x := {echo hello world}; $x
+.EE
+It is important to note that the value of
+.B $*
+is lost every time a braced block is entered, so
+for instance, the following command prints an empty string:
+.EX
+ {{echo $*}} hello world
+.EE
+.PD
+.SS Built-in Commands
+The term ``built-in command'', or just ``builtin'', is used somewhat loosely
+in this document to refer to any command that is executed
+directly by the shell; most built-in commands are defined
+by externally loaded modules; there are a few that are not,
+known as ``internal'' builtins, listed below.
+.PP
+Given
+.IR sh 's
+ability to pass compound commands (braced blocks) as
+arguments to other commands, most control-flow
+functionality that is traditionally hard-wired into a shell
+is in
+.I sh
+implemented by loadable modules. See
+.IR sh-std (1),
+.IR sh-expr (1),
+and
+.IR sh-tk (1)
+for more details.
+.PP
+There are two classes of built-in commands;
+the first class, known simply as ``builtins'', are used in
+the same way as normal commands, the only difference
+being that builtins can raise exceptions, while external
+commands cannot, as they are run in a separate process.
+The second class, known as
+``builtin substitutions'' can only be used as the first
+word of the command in the
+.B ${}
+operator. The two classes exist in different name-spaces:
+a builtin may do something quite different from a
+builtin substitution of the same name.
+.PP
+In general, normal builtins perform some action
+or test some condition;
+the return status of a normal builtin usually
+indicates error status or conditional success. The
+rĂ´le of a substitution builtin is to yield a value,
+(possibly a list)
+which is substituted directly into place as part
+of the argument list of a command.
+.PP
+.PD 0
+.HP
+.BI @ " command ..."
+.br
+Execute
+.I command
+in a subshell, allowing (for instance) the name-space to be
+forked independently of main shell.
+.HP
+.BI run " file ..."
+.br
+Execute commands from
+.IR file .
+.B $*
+is set for the duration to the remainder of the argument list following
+.IR file .
+.HP
+.BI builtin " command ..."
+.br
+Execute
+.I command
+as usual except that any command defined by an external
+module is ignored in favour of the original meaning.
+This command cannot be redefined by an external module.
+.HP
+.B exit
+.br
+Terminate the current process.
+.HP
+.BI load " path..."
+.br
+.B Load
+tries to load each of its arguments as a builtin module
+into
+.IR sh .
+If a module load succeeds, each builtin
+command defined by that module is
+added to the list of builtin commands.
+If there was a previous definition of the command,
+it is replaced, with the exception of internal
+.I sh
+builtins, which are covered up and reappear when
+the module is unloaded. If a module with
+the same
+.I path
+has already been loaded,
+.I sh
+does not try to load it again.
+Unless the path begins with
+.B /
+or
+.BR ./ ,
+the shell looks in the standard builtins directory
+.B /dis/sh
+for the module.
+If a load fails, a
+.B bad module
+exception is raised.
+.HP
+.BI unload " path..."
+.br
+.B Unload
+undoes previous load commands. To succeed,
+.I path
+must be the same as that given to a previous
+invocation of
+.BR load .
+.HP
+.B loaded
+.br
+.B Loaded
+prints all the builtin commands currently
+defined, along with the name of the module that defined them.
+Internally defined commands are tagged with
+module
+.BR builtin .
+.HP
+.BI whatis " name ..."
+.br
+Print the value of each
+.I name
+in a form suitable for input to
+.IR sh .
+The forms are:
+.RS 10
+.TP
+.I varname = "value..."
+.I Varname
+is a non-nil environment variable.
+.TP
+.BI load\ module ;\ name
+.I Name
+has been defined as a builtin by the externally loaded
+.IR module .
+.TP
+.BI load\ module ;\ ${ name }
+.I Name
+has been defined as a builtin substitution by the externally loaded
+.IR module .
+.TP
+.BI builtin\ name
+.I Name
+is defined as a builtin internally by
+.IR sh .
+.TP
+.BI ${ name }
+.I Name
+is defined as a builtin substitution
+internally by the shell.
+.TP
+.I pathname
+The completed pathname of an external file.
+.RE
+.HP
+.B ${builtin
+.I command
+...
+.B }
+.br
+Does for substitution builtin commands
+what
+.B builtin
+does for normal commands.
+.HP
+.B ${loaded}
+.br
+The
+.B loaded
+builtin substitution yields a list of the names of all
+the modules currently loaded, as passed to
+.BR load .
+.HP
+.BI ${quote \ list }
+.br
+.B Quote
+yields a single element
+list which if reparsed by the shell
+will recreate
+.IR list .
+.HP
+.BI ${bquote \ list }
+.br
+Same as
+.B quote
+except that items in
+.I list
+that are known to be
+well-formed command blocks are not quoted.
+.HP
+.BI ${unquote \ arg}
+.br
+.B Unquote
+reverses the operation of
+.BR quote ,
+yielding the original list of values. For example,
+.BI "${unquote ${quote " list }}
+yields
+.IR list .
+A list quoted with
+.B bquote
+can only be unquoted by parsing.
+.PD
+.SS Environment
+The
+.I environment
+is a list of strings made available to externally executing commands by the
+.B env
+module
+(see
+.IR env (2)).
+If the
+.B env
+module does not exist or cannot be loaded, no error will be
+reported, but no variables can be exported to external commands.
+.I Sh
+creates an environment entry for each variable whose value is non-empty.
+This is formatted as if it had been run through
+.BR ${quote} .
+Note that in order for a variable to be exported, its
+name must conform to the restrictions imposed
+by
+.IR env (3);
+names that do not will not be exported.
+.PP
+When
+.I sh
+starts executing it reads variable definitions from its
+environment.
+.PP
+Internally, the shell holds a
+.IR context ,
+which holds a stack of environment variables, the
+current execution flags and the list of built-in modules.
+A copy is made whereever parallel access to the context might
+occur. This happens for processes executing
+in a pipeline,
+processes run asynchronously with
+.BR & ,
+and in any builtin command that runs a shell command
+asynchronously.
+.SS Exceptions
+When
+.I sh
+encounters an error processing its input, an exception is raised,
+and if the
+.B -v
+flag is set, an error message is printed to
+standard error.
+An exception causes processing of the current command to terminate
+and control to be transferred back up the invocation stack.
+In an interactive shell, the central command processing loop
+catches all exceptions and sets
+.B $status
+to the name of the exception.
+Exceptions are not propagated between processes. Any
+command that requires I/O redirection is run in a separate
+process, namely pipes
+.RB ( | ),
+redirections
+.RB ( > ,
+.BR < ,
+.BR >> ,
+and
+.BR <> ),
+backquote substitution
+(\f5`\fP, \f5"\fP)
+and background processes
+.RB ( & ).
+Exceptions can be raised and rescued using
+the
+.B raise
+and
+.B rescue
+functions in the standard builtins module,
+.BR std .
+(See
+.IR sh-std (1)).
+Names of exceptions raised by
+.I sh
+include:
+.TP 10
+.B parse error
+An error has occurred trying to parse a command.
+.TP
+.B usage
+A builtin has been passed an invalid set of arguments;
+.TP
+.B bad redir
+An error was encountered trying to open files prior
+to running a process.
+.TP
+.B bad $ arg
+An invalid name was given to the $ or ${} operator.
+.TP
+.B no pipe
+.I Sh
+failed to make a pipe.
+.TP
+.B bad wait read
+An error occurred while waiting for a process to exit.
+.TP
+.B builtin not found
+A substitution builtin was named but not found.
+.SS Special Variables
+The following variables are set or used by
+.IR sh .
+.PD 0
+.TP \w'\fL$promptXX'u
+.B $*
+Set to
+.IR sh 's
+argument list during initialization.
+Whenever a
+braced block
+is executed, the current value is saved and
+.B $*
+receives the new argument list.
+The saved value is restored on completion of the
+.BR block .
+.TP
+.B $apid
+Whenever a process is started asynchronously with
+.BR & ,
+.B $apid
+is set to its process id.
+.TP
+.B $ifs
+The input field separators used in backquote substitutions.
+If
+.B $ifs
+is not set in
+.IR sh 's
+environment, it is initialized to blank, tab and newline.
+.TP
+.B $prompt
+When
+.I sh
+is run interactively, the first component of
+.B $prompt
+is printed before reading each command.
+The second component is printed whenever a newline is typed and more lines
+are required to complete the command.
+If not set in the environment, it is initialized by
+.BR "prompt=('%\ '\ '')" .
+.TP
+.B $status
+Set to the wait message of the last-executed program,
+the return status of the last-executed builtin
+(unless started with
+.BR &),
+or the name of the last-raised exception, whichever
+is most recent.
+When
+.I sh
+exits at end-of-file of its input,
+.B $status
+is its exit status.
+.PD
+.SS Invocation
+If
+.I sh
+is started with no arguments it reads commands from standard input.
+Otherwise its first non-flag argument is the name of a file from which
+to read commands (but see
+.B -c
+below).
+Subsequent arguments become the initial value of
+.BR $* .
+.I Sh
+accepts the following command-line flags.
+.PD 0
+.TP \w'\fL-c\ \fIstring\fLXX'u
+.BI -c " string"
+Commands are read from
+.IR string .
+.TP
+.B -i
+If
+.B -i
+is present, or
+.I sh
+is given no arguments and its standard input is a terminal,
+it runs interactively.
+Commands are prompted for using
+.BR $prompt .
+This option implies
+.BR -v .
+.TP
+.B -l
+If
+.B -l
+is given or the first character of argument zero is
+.BR - ,
+.I sh
+reads commands from
+.BR /lib/sh/profile ,
+if it exists, and then
+.BR ./lib/profile ,
+if it exists, before reading its normal input.
+.TP
+.B -n
+Normally,
+.I sh
+forks its namespace on startup; if
+.B -n
+is given, this behaviour is suppressed.
+.TP
+.B -v
+Within a non-interactive shell, informational messages
+printed to standard error are usually disabled;
+giving the
+.B -v
+flag enables them.
+.TP
+.B -x
+Print each simple command to stderr before executing it.
+.PD
+.SH SOURCE
+.B /appl/cmd/sh/sh.y
+.SH "SEE ALSO"
+.IR sh (1),
+.IR sh-std (1),
+.IR sh-expr (1),
+.IR sh-file2chan (1),
+.IR sh-tk (1),
+.IR sh-arg (1),
+.IR sh-regex (1),
+.IR sh-string (1),
+.IR sh-csv (1),
+.IR sh (2),
+.IR env (2)
+.SH BUGS
+Due to lack of system support, appending to
+a file with
+.B >>
+will not work correctly when there are
+multiple concurrent writers (but see the
+examples section of
+.IR sh-file2chan (1)
+for one solution to this).
+.PP
+While it
+.I is
+possible to use the shell as a general
+purpose programming language, it is a very slow one!
+Intensive tasks are best done in Limbo, which is a much
+safer language to boot.