MASH(1)                                                   MASH(1)

     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 quo-
          tation 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 exe-
          cuted 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

     Page 1                       Plan 9            (printed 11/23/24)

     MASH(1)                                                   MASH(1)

          in the current directory and then in /dis.  The .dis exten-
          sion 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 char-
          acter * 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 sepa-
          rated by -, standing for all characters lexically between
          the two. The character / must appear explicitly in a pat-
          tern. 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 prefix-
          ing /tmp.

          A quoted word is a sequence of characters surrounded by sin-
          gle 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) buil-
               tin.
          $"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 out-
               put, splitting it into a list of words, using the
               whitespace characters (space, tab, newline and carriage
               return) as separators.

     Page 2                       Plan 9            (printed 11/23/24)

     MASH(1)                                                   MASH(1)

          "{commands}
               mash executes the commands and reads the standard out-
               put, 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 construc-
               tion of non-linear pipelines. For example, the follow-
               ing runs two commands old and new and uses cmp to com-
               pare 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 distribu-
               tive. Otherwise the lists are concatenated pairwise.

        Free Carets
          In most circumstances, mash will insert the ^ operator auto-
          matically 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 immedi-
          ately 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 redi-
          rected 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.

     Page 3                       Plan 9            (printed 11/23/24)

     MASH(1)                                                   MASH(1)

     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 com-
               mands separated by & or ;.  The second form is executed
               with a new scope. Either form can be followed by redi-
               rections.
          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 func-
               tion 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 vari-
               able.

     Page 4                       Plan 9            (printed 11/23/24)

     MASH(1)                                                   MASH(1)

          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 com-
               mands 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 con-
               catenation, == and != are the equality operators evalu-
               ating to true or the null list, depending on the equal-
               ity 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

     Page 5                       Plan 9            (printed 11/23/24)

     MASH(1)                                                   MASH(1)

          module defines the following commands
          env
               Print global and local variables. Global variables are
               displayed using a name=value format, and local vari-
               ables 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 con-
               tain 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 addition-
               ally 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

     Page 6                       Plan 9            (printed 11/23/24)

     MASH(1)                                                   MASH(1)

          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.

     Page 7                       Plan 9            (printed 11/23/24)