NAME
- mash - programmable shell
SYNOPSIS
- mash [ -denx ][ -ccommand ] [ file [ arg ... ]]
DESCRIPTION
-
Mash
is an older alternative to the original Inferno shell
(now
tiny(1)).
Mash
is a programmable shell that also allows the definition of simple dependency
rules, resembling those of Unix
make.
It executes commands read from standard input
or a file or, with the
-c
flag, from
mash's
argument list. Its syntax and
semantics are similar to that of Plan 9's
rc.
- Invocation
-
If
mash
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
-c
below). Subsequent arguments
become the initial value of
$args.
Mash accepts the following
command-line flags.
- -c string
- Commands are read from string.
- -d
- Dump parsed commands before execution.
- -e
- Fail if a top level command does.
- -n
- Parse but do not execute.
- -x
- Print each simple command before executing it.
If invoked without arguments mash first runs the commands found in /lib/mashinit.
- Command Lines
-
Each command is terminated with an ampersand or a semicolon (& or ;).
When reading from
/dev/cons
a newline
not escaped with a backslash (\) is treated as a semicolon.
Mash
does not
wait for a command followed by
&
to finish executing before starting the
following command.
A number-sign (#) and any following characters up to (but not including) the next newline are ignored, except in quotation marks.
- Simple Commands
-
A simple command is a sequence of words interspersed with I/O
redirections. If the first word is the name of a
mash
function or of one of
mash's
built-in commands, it is executed by
mash.
Otherwise, if the name
starts with a slash
(/),
it must be the path name of a Dis
file to be loaded
and executed. Names containing no initial slash are searched for in the
current directory and then in
/dis.
The
.dis
extension need not be
supplied.
The keywords are
case else fn for hd if in len rescue tl while
- Words and Variables
-
A number of constructions may be used where
mash's
syntax requires a
word to appear. In many cases a construction's value will be a list of
strings rather than a single string.
The simplest kind of word is the unquoted word: a sequence of one or more characters none of which is a blank, tab, newline, or any of the following:
# : ; ! ~ @ & | ^ $ = " ` ' { } ( ) < >An unquoted word that contains any of the characters *,? or [ is a pattern for matching against file names. The character * matches any sequence of characters, ? matches any single character, and [ class ] matches any character in the class. The class may also contain pairs of characters separated by -, standing for all characters lexically between the two. The character / must appear explicitly in a pattern. A pattern is replaced by a list of words, 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,x=/tmp; echo $x^/*.c;
matches /tmp/*.c, rather than matching /*.c and then prefixing /tmp.A quoted word is a sequence of characters surrounded by single quotes ('). A single quote is escaped with a backslash.
Each of the following is a word.
- $identifier
- The identifier after the
$
is the name of a variable whose value is
substituted. Variable values are lists of strings. It is an error if the
named variable has never been assigned a value.
- $number
- See the description of rules for the
mash-make(1)
builtin.
- $".I identifier
- The value is a single string containing the components of the named
variable separated by spaces.
- `{commands}
- mash
executes the commands and reads the standard output, splitting
it into a list of words, using the whitespace characters (space, tab,
newline and carriage return) as separators.
- {.IB commands }
- mash
executes the commands and reads the standard output, splitting
it into a list of words, using the whitespace characters (space, tab,
newline and carriage return) as separators.
- <{commands}
- >{commands}
- The commands are executed asynchronously with their standard
output or standard input connected to a pipe. The value of the word
is the name of a file referring to the other end of the pipe. This
allows the construction of non-linear pipelines. For example, the
following runs two commands
old
and
new
and uses
cmp
to compare their outputs
cmp <{old} <{new}; - (expr)
- mash
evaluates
expr
as an expression. The value is a (possibly null) list of words.
Expressions are described in detail below.
- word^word
- The ^ operator concatenates its two operands. If either operand is a singleton, the concatenation is distributive. Otherwise the lists are concatenated pairwise.
- Free Carets
-
In most circumstances,
mash
will insert the
^
operator automatically
between words that are not separated by white space. Whenever one of
$
'or
`
(dollar, single quote or back quote)
follows a quoted or unquoted word or an unquoted word follows a
quoted word with no intervening blanks or tabs, a
^
is inserted between
the two. If an unquoted word immediately follows a
$
and contains a
character other than an alphanumeric, or underscore, a
^
is inserted before
the first such character. Thus
- limbo -$flags $stem.b
is equivalent to
- limbo -^$flags $stem^.b
- I/O Redirections
- The sequence >file redirects the standard output file (file descriptor 1, normally /dev/cons) to the named file; >>file appends standard output to the file. The standard input file (file descriptor 0, also normally /dev/cons) may be redirected from a file by the sequence <file. The sequence <>file opens the file for read/write and associates both file descriptor 0 and 1 with it.
Compound Commands
-
A pair of commands separated by a pipe operator
(|)
is a command. The
standard output of the left command is sent through a pipe to the
standard input of the right command.
Each of the following is a command.
- if ( expr ) command1
- if ( expr ) command1 else command2
- The
expr
is evaluated and if the result is not null, then
command1
is executed. In the second form
command2
is executed if
the result is null.
- for ( name in list )command
- The
command
is executed once for each word in
list
with that
word assigned to
name.
- while ( expr ) command
- The
expr
is evaluated repeatedly until its value is null. Each time it
evaluates to non-null, the command is executed.
- case expr { pattern-list => command ... }
- case expr-list { pattern => command ... }
- In the first form of the command the
expr
is matched against a series of lists of regular expressions (See
regex(2)).
The command associated with the matching expression is executed.
In the second form the
command
associated with the first pattern to match one of the words in
expr-list
is executed. An
expr-list
will never match a
pattern-list.
- {commands}
- @{commands}
- Braces serve to alter the grouping of commands implied by operator
priorities. The body is a sequence of commands separated by
&
or
;.
The second form is executed with a new scope. Either form can be
followed by redirections.
- fnname{list}
- fnname
- The first form defines a function with the given
name.
Subsequently,
whenever a command whose first word is
name
is encountered, the
current value of the remainder of the command's word list will be
assigned to the local variable
args,
in a new scope, and
mash
will execute the list. The second form removes
name's
function definition.
- name=list
- name:=list
- The first form is an assignment to a variable. If the name is currently
defined as a local variable its value will be updated. Otherwise a
global variable with the given name will be defined or updated. The
second form is an explicit definition or update of a local variable.
- list:list
- list:list{commands}
- word:~word{commands}
- These forms define dependencies and rules for the make loadable builtin. The first form defines a simple dependency, the second a dependency with an explicit rule. The third form defines an implicit rule where the left-hand word is a file pattern, the right-hand word is the prerequisite. The right-hand word and the commands can contain references to the characters matched by the * meta-character in the pattern ($1 evaluates to the characters matched by the first *, $2 the second and so on; $0 is the entire match).
- Expressions
-
Expressions evaluate to possibly null lists of strings. A word is an
expression. An expression may take one of the following forms
- ( expr )
- Parentheses are used for grouping.
- hd expr
- tl expr
- len expr
- ! expr
- hd
is the first element of a list,
tl
the remainder.
len
is the length of
a list. Both evaluate to the null list if their operand is a null list.
!
is the not operator and evaluates to true for a null list or to a null list
otherwise.
- expr ^ expr
- expr :: expr
- expr == expr
- expr != expr
- expr ~ expr
- ^ is concatenation (as defined above), :: is list concatenation, == and != are the equality operators evaluating to true or the null list, depending on the equality or inequality of the two operands. ~ is the match operator, true if a singleton string matches one of a list of regular expressions, or one of a list of strings matches a regular expression. (If neither operand is a singleton it evaluates to the null list.) ^ has the highest precedence, followed by :: followed by the other three. All associate to the left except ::.
- Built-in Commands
-
Mash
supports loadable modules of builtins. The
Mashbuiltin
module definition and description is in
mash.m.
One such module,
builtins,
is loaded before
mash
begins parsing. This module defines the following commands
- env
- Print global and local variables. Global variables are displayed using a
name=value
format, and local variables using a
name:=value
format.
- eval
- Concatenate arguments and use as mash input.
- exit
- Cause
mash
to raise an
exit
exception.
- load file
- Load a builtin module. The
file
must be a module with type
Mashbuiltin.
The argument
file
is assumed to contain a path to the loadable module. If no such module
is found then the string
/dis/lib/mash/
is prepended to
file
and the load is retried.
- prompt
- prompttext
- prompttext contin
- When called with no arguments causes the current value of the
mash
prompt to be printed to standard output. The default value is
mash%.
The second form sets a new prompt. The final form sets a new prompt
and additionally a continuation string. Initially the continuation
string is set to a single tab character.
Mash
uses the continuation string in place of the prompt string to indicate that
the preceding line has been continued by escaping with a final backslash
(\)
character.
- quoteargs...
- Print arguments quoted as input for
mash.
- run -[denx] file [arg...]
- Interpret a file as input to
mash.
- timecmd [arg...]
- Time the execution of a command. The total execution time is reported
in seconds and on standard error when the command completes.
- whatisname
- Print variable, function or builtin. The object given by name is described on standard output in a format that reflects its type.
The make loadable builtin provides `make` functionality. The tk loadable builtin provides control over some of the visual elements of a mash window.
- Adding Builtins
- New builtins can be added to mash by creating a Dis module that can be loaded with a Mashbuiltin module interface (defined in mash.m). The new module is loaded with the builtin load command which calls its mashinit function to initialise it with an argument containing the load command line. The function should use this call to register the set of builtins that the module will provide using the Env.defbuiltin function. Thereafter, each time one of the registered builtins is invoked the module's mashcmd function is called passing as an argument a list containing the invoked builtin name and its arguments. See the examples in mash/builtins.b, mash/make.b, and mash/tk.b.
FILES
-
/lib/mashinit
/dis/lib/mash SOURCE
- /appl/cmd/mash
SEE ALSO
-
mash-tk(1),
mash-make(1),
regex(2)
Tom Duff, ``Rc - The Plan 9 Shell'', in the Plan 9 Programmer's Manual , Second Edition, Volume 2.
| MASH(1) | Rev: Tue Jan 29 13:11:30 GMT 2008 |