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.
&
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
The following variables are pre-defined or used by the shell:
Although not predefined, the
To redirect standard input from a file, use
or
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
would print the contents of all the regular files under the current
directory. In this example the name has an implicit
"
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
"
The syntax
is similar, but it creates an output channel to _cmd2_ given as an
argument to _cmd_.
Most other Clive commands are usually linked into the same
Concatenation:
Variables as maps:
Command substitution:
Predicates and redirections:
Show all Go sources under the current directory
Long-list them:
Grep them for
Define a long-list function:
shift builtin drops the first name in the
named variable, or in
argv if no variable
name is given.
argv
argv0
sts
path
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.
.
cmd... < name
cmd... <[in] name
cat <,-
" 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.
<[in:out1,out2...]{...}
> file
>> file
cmd >[err]/tmp/errors
cmd >[out,err]/tmp/outputanderrors
cmd >[out:err]
cmd <{cmd2...}
cmd <{cmd2... | lines}
cmd <{cmd2... | words}
cmd <{cmd2... | all}
cmd <[in2]{cmd2...}
" to pipe arbitrary
channels.
ql
cmd >[out2]{cmd2...}
BUILT-IN COMMANDS
The following commands are built into :
cd [name]
pwd
exit [sts]
ql using the given argument, if
any, as the exit status.
break
for,
while, or
cond) and
continue executing the next command.
wait {tag}
& in the
pipeline).
type {name}
name. It may be a
builtin, a function, an environment variable or the path used to
execute it as a command.
fork {resource}
ns,
io,
dot, or
env.
shift [var]
argv by
default).
ql binary, use
type
to discover which ones are external and which ones are not.
fooEXAMPLES
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
> x=(a b)
> echo $x^x
ax bx
> y=($x c d)
> echo $y
a b c d
> echo $#y
4
> x=([a b] [x y z])
> echo $x
a x
> y=$x[x]
> echo $y
y z
> echo $#y
2
Also,
> for x <{eco a ; eco b} {
> eco -u $x
> }
a
b
> for x <{eco a b} {
> eco -u $x
> }
a b
which can be done also as:
> for line <{lf -g ,- | lines} {
> do something to $line
> }
> 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
Issue an error to standard error:
eco errors >[out:err]
Or
pf <,~*.go
List all regular files under the current directory:
lf -g .,name~*.go | pf
lf -u ,-
lf -u ,- |pf -l
:
/zx/sys/src/clive/cmd/ql
gr -u foo <,-
func ll {
lf $argv | pf -l
}
SOURCE
/zx/sys/src/clive/cmd/ql/exampleSEE ALSO
contains examples for all the syntax understood by the shell.