User's manual. Section 1.

QL(1): clive shell


USAGE

        usage: ql [-DLNYcinux] [file] ...
            -D: debug
            -L: debug lex
            -N: debug nodes
            -Y: debug yacc
            -c: run args as a command
            -i: interactive
            -n: dry run
            -u: do not use unix IO
            -x: print commands as they are run
        

DESCRIPTION

Ql is the Clive shell. In reads commands from either the standard input or a file given in the command line and executes them. Flag -c may be used to make the arguments represent a command to be executed and not file names.

When executing a file, the entire file is read before processing its contents. It is safe to edit or remove the file while it runs. Arguments following the given file name are used as arguments for the script file being executed. Under flag -c the command is supplied in the argument list.

Text enclosed in single or reverse quotes, like '...' and `....` is taken verbatim as a single word.

The # character can be used to write line comments. Empty lines are ignored. All other text is parsed as a series of commands. Each command is executed only after its source text has been fully parsed. For example, commands within a block are not executed until the entire block is read from the input text and parses correctly.

The prompt is "> ". Any run of ">" characters (and blanks) at the start of line are silently discarded, to help the user in selecting command lines and executing them again.

Commands are one or more words (none for the empty command) terminated either by a new-line character or using a ";". A backslash before a new-line converts the new-line into a space, to type long commands in multiple lines. After a pipe-line character, a new-line may be typed and it will be ignored, for the same purpose.

Command words are separated by runs of white space, unless they result from constructs (described later) which preserve words as generated by other commands.

A command can be:

  • A pipe line
  • A block of commands
  • A source command
  • A function definition, terminated with a new-line or a ; character.
  • A for loop
  • A while loop
  • A cond (conditional) structure
  • An assignment.
In all cases, optional redirections for input and output can follow. An optional & can be added at the end if ql should not wait for the command to terminate before prompting for another command. This is called a background command. The & operator can be followed by a name to tag the command. The wait builtin waits for background commands and can be given tags as arguments to wait just for those commands. Without arguments, wait waits for all outstanding background commands.

A pipe-line is a series of simple commands separated by "" characters, perhaps a single one, or an empty one. Here, the in channel of a command is the out channel of the preceding one. The syntax "|[err]", (where err can be any channel name) connects the err channel of the preceding command to the in channel of the following one. The syntax "|[x:y]" connects the y channel of the preceding command to the x channel of the following one. The general syntax permits arbitrary networks of channels and has the form "|[x:y,z;p:q,r...]"

The first name is a list of names used as a command is understood as the command name. If it matches the name of a function, the function is executed as a command. If it matches the name of a built-in, the built-in is executed as a command. If the name starts with "/", "./", or "../", it is uses as a relative path to the file for the command. Otherwise, the name is appended to each of the directories in $path (or $PATH if the former is not defined) and the first file found with execute permissions is run as a command. The type builtin may be given one or more names and prints the type of name (function, builtin, etc.).

When a command terminates, $sts contains the exit status for the command, which is empty for success.

A block of commands is a series of commands encondes in "{" and "}" characters.

A source command has the form

        < file
        

and executes the text in file as commands. This can be used to include input for the shell from another file.

Functions may be defined line in

        func name { cmds }
        

Once defined, the function name may be used as a command. Arguments supplied are available in $argv within the function. The name of the function is in $argv0. The status of the last command in the function is used as the status of the function.

The for control structure has the form

        for name val... { cmds }
        

and sets $name to each one of the names that follow and runs the body block for each value.

When using the form

        for name { cmds }
        

the loop iterates over the messages received from the standard input and not over the names given in the command line.

The while control structure has the form

        while cmd { cmds }
        

and executes the body block while the command used as a condition terminates with success.

The cond control structure is the only conditional and has the form

        cond {
            cmd1
            cmd2
            ...
            cmdn
        }
        

With optional or branches added, like in:

        cond {
            ...
        } or {
            ...
        } or {
            ...
        } ...
        

Each one of the or branches (perhaps a single one if no or is used) executes in order until one succeeds. An or branch executes the commands in its block in order until one fails or until the last command runs. If the last command runs, the or branch succeeds. In short, the conditional is an or for ands of commands. You might think of all commands in a block as the conditions for the last command in that block, which might be considered as the body of a conventional if construct.

VARIABLES

A name list (as used in a command) may include names starting with "$" which are replaced by the values of the conrresponding (environment) variables. Each variable is a list of names, and the substitution preserves the name boundaries. Variable values are never parsed as control structures and are expanded just once, as part of a name list.

Within a name, the characters "=$" are not special and are considered part of the name, but the "=" character is still considered the assignment operator within the first name of each line. This produces the desired results in most cases and avoids the need to quote the "=" character in predicates and command arguments.

A variable may be assigned a value using

        name=value
        

or

        var←name
        

where value is, in general, a list of names. For example:

        name = (a b c)
        

The syntax "$name" expands to the series of names in the value of the variable. The number of elements is retrieved using "$#name". The syntax "$^name" can be used to expand the value of the variable to a single name (with words joined by single spaces). Each element in the list can be retrieved using "$name[0]", "$name[1]", etc. The index can be a variable, as in "$name[$idx]", but using "$$name" is a syntax error. The assignment

        name[n]= value
        

updates the value of that position in the variable. Even if value is a list, the variable still retains the same number of elements. One of the examples further illustrates this.

Variables can be also maps, defined as in

        name=([key1 values...] [key2 values...] ...)
        

The expression "$name" expands to the set of keys for the map. The expression "$name[key]" expands to the values for that key. See the example section.

Lists can be concatenated using the "^" operator. If both arguments have the same number of elements, the result is a list with the same number of elements and each one is the concatenation of the same element in both lists. If one of the lists has one element, that element is concatenated to each one of the elements of the other argument. Otherwise, it is an error to try to concatenate the lists. But you might use:

        x=($y and other values)
        

The shift builtin drops the first name in the named variable, or in argv if no variable name is given.

The following variables are pre-defined or used by the shell:

argv
the argument list of scripts and functions
argv0
the name of the script
sts
the exit status of the last command. For blocks, the one of their last command
path
the preferred locations to search for external commands.
The user may assign values to them.

Although not predefined, the NS variable contains the textual representation of the name space, as shown in [cite: intro(1)], when name spaces are used.

REDIRECTIONS

Optional edirections can be written at the end of commands. Note that a "<" at the start of a command line is a source command and not a redirection.

To redirect standard input from a file, use

        cmd... < name
        

or

        cmd... <[in] name
        

The name in brackets indicates the channel that is to be defined as the input channel from the named file. Here, _name_ is the name for a file (tree), including both a path and a predicate, thus

        cat <,-
        

would print the contents of all the regular files under the current directory. In this example the name has an implicit "." as the path and a "-", which is actually "type=-", as the predicate; together it means all the regular files under the current directory). All those files are streamed through the _in_ channel for the command.

To redirect standard output to a file, use

        > file
        

to create the output file (or truncate it). Or use

        >> file
        

to append to that file. In this case, for safety, no predicates are accepted; only a file path.

Output channel names may be given after the redirection operator to redirect output for those channels to the named file, as in:

        cmd >[err]/tmp/errors
        cmd >[out,err]/tmp/outputanderrors
        

The syntax

        cmd >[out:err]
        

makes the _out_ channel be that used as the _err_ channel. It is a _dup_, and channels are named in the same order used in the assignment, as a remainder of which channel is the old one and which one is the new one.

The syntax

        cmd <{cmd2...}
        

Takes the output from _cmd2_ and interpolates it in the command line at that place. This is command substitution. Each message printed by _cmd2_ is used as a different word in the command line. There are examples later, but these are usual usages:

        cmd <{cmd2... | lines}
        cmd <{cmd2... | words}
        cmd <{cmd2... | all}
        

The syntax

        cmd <[in2]{cmd2...}
        

creates the _in2_ channel for _cmd_ as an input channel that will convey the output for the enclosed _cmd2_, and the whole construct is replaced by the name of the channel. When Clive commands convert the arguments to input channels, they notice that the name is for an input channel and retrieve input from there. The general construct is "<[in:out1,out2...]{...}" to pipe arbitrary channels.

The syntax

        cmd >[out2]{cmd2...}
        

is similar, but it creates an output channel to _cmd2_ given as an argument to _cmd_.

BUILT-IN COMMANDS

The following commands are built into ql:
cd [name]
Change current directory to the given one or the home directory if none.
pwd
Print the working directory.
exit [sts]
Terminate the execution of ql using the given argument, if any, as the exit status.
break
Stop the enclosing construct (a for, while, or cond) and continue executing the next command.
wait {tag}
Wait for previous background commands to complete. If no tag is supplied, it waits for all of them. Otherwise, it waits for the pipeline with the given tag (an optional name written after the & in the pipeline).
type {name}
inform of the type of object known as name. It may be a builtin, a function, an environment variable or the path used to execute it as a command.
fork {resource}
dups the resource, which can be ns, io, dot, or env.
shift [var]
Drop the first element of the given variable (argv by default).

Most other Clive commands are usually linked into the same ql binary, use type to discover which ones are external and which ones are not.

EXAMPLES

Variables as lists:

        > x=(a b c)
        > x[0]=(q w e)
        > echo $x
        q w e b c
        > echo $#x
        3
        > echo $x[0]
        q w e
        > x=<{eco $x}
        > echo $x
        q w e b c
        > echo $#x
        1
        > x=<{eco $x|words}
        > echo $#x
        5
        

Concatenation:

        > x=(a b)
        > echo $x^x
        ax bx
        > y=($x c d)
        > echo $y
        a b c d
        > echo $#y
        4
        

Variables as maps:

        > x=([a b] [x y z])
        > echo $x
        a x
        > y=$x[x]
        > echo $y
        y z
        > echo $#y
        2
        

Command substitution:

        > for x <{eco a ; eco b} {
        > eco -u $x
        > }
        a
        b
        > for x <{eco a b} {
        > eco -u $x
        > }
        a b
        
    Also,
        > for line <{lf -g ,- | lines} {
        > do something to $line
        > }
        
    which can be done also as:
        > lf -g ,- | lines | for line {
        > do something to $line
        > }
        

        > eco -u <[in2]{eco a}
        |<in2
        
        > pf <[in2]{eco a} <[in3]{eco b c}
        c ---------      0 |<in2
        a
        c ---------      0 |<in3
        b c
        

Predicates and redirections:

    Issue an error to standard error:
        eco errors >[out:err]
        

    Show all Go sources under the current directory

        pf <,~*.go
        
    Or
        lf -g .,name~*.go | pf
        
    List all regular files under the current directory:
        lf -u ,-
        

    Long-list them:

        lf -u ,- |pf -l
        

    Grep them for foo:

        gr -u foo <,-
        

    Define a long-list function:

        func ll {
            lf $argv | pf -l
        }
        

SOURCE

  • /zx/sys/src/clive/cmd/ql

SEE ALSO

  • /zx/sys/src/clive/cmd/ql/example contains examples for all the syntax understood by the shell.


User's manual. Section 1.