User's manual. Section 1.

QL(1): clive shell



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:

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

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

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

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

When using the form

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

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

With optional or branches added, like in:

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.


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


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

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

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

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:

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:

the argument list of scripts and functions
the name of the script
the exit status of the last command. For blocks, the one of their last command
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.


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


        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

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

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:

The syntax

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

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:

The syntax

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

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


The following commands are built into ql:
cd [name]
Change current directory to the given one or the home directory if none.
Print the working directory.
exit [sts]
Terminate the execution of ql using the given argument, if any, as the exit status.
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.


Variables as lists:

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


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

Variables as maps:

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

Command substitution:

        > for x <{eco a ; eco b} {
        > eco -u $x
        > }
        > for x <{eco a b} {
        > eco -u $x
        > }
        a b
        > 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}
        > pf <[in2]{eco a} <[in3]{eco b c}
        c ---------      0 |<in2
        c ---------      0 |<in3
        b c

Predicates and redirections:



User's manual. Section 1.