.th SH VI 9/15/77 .if t .tr *\(** .sh NAME sh \- a shell (command interpreter) .sh SYNOPSIS .bd sh [ .bd \-V ] [ .bd \-v ] [ .bd \-t ] [ .bd \-c ] [ .bd \-i ] [ name [ arg ... ] ] .sh DESCRIPTION .it Sh is a command interpreter. It arranges and interprets command lines and the contents of command files. It is a modification of the standard shell .it sh (I), and almost completely upward compatible therewith. The intent, in working on a new shell, is to provide an environment which is more easily tailored to the wishes of each individual user. Most new features of this shell, especially the .it alias feature, are toward this end. Later versions of this shell may include improvements to the command language of the shell and allow more easy repetition of commands. The intent here is to make the command language more resemble a high-level language \- C being the natural choice for \s-2UNIX\s0, and to provide some means of repeating modified commands without retyping, perhaps akin to the \s-2INTERLISP\s0 .it redo feature. The eventual goal is a C\-shell, .it csh (or ``seashell'' if you prefer.) .s3 .bd "Notes:" this shell is currently available as .it "/usr/pascal/sh" on the Cory and Evans \s-2UNIX\s0 systems at UC Berkeley. We discuss the major features of the shell beginning with the objects of the shell world, then the lexical structure of the shell input, the syntactic structure, details on command execution, pre-defined variables, start-up processing, options, and finally a list of the built-in commands with a simple description of each. This documentation is neither fully polished nor devoid of forward references. .it Sh was a ``working'' version of the new .it csh which became useful when the completion of .it csh was delayed. It is hoped that this documentation will serve as a reference for .it sh users who have lived, to this point, by word-of-mouth information. .s3 .bd "Objects." The major .it objects of the shell world are the .it variables and the .it "argument list" which consists of specially named and initialized variables. The variables in the argument list have numeric names, e.g. `1' and `2'. The other variables have alphabetic names, composed of upper and lower case letters. Variable names may be up to 20 characters long. There is a distinction between a variable existing and not existing, akin to a variable being on the .it "a-list" in \s-2LISP\s0. Initially, no variables exist; in shell terminology, no variables are .it set. Variables have string values only; some numeric operations are defined on variables, but the representation of variables is always as a string. Some variables have special meaning to the shell; thus .it pid is the process id of the shell, set to a string with this value when the shell is created. These variables have, however, no special status. They may be manipulated as any other variables are, with the caveat being that these manipulations may directly affect the behavior of the shell. One other point to be noted is that some of the built-in variables are essentially `toggles'; that is, the shell cares only if they are set or not, not what their value is. The standard way to set such a variable is to set it to be the null string. .s3 .bd "Lexical structure." The primary lexical structuring of the input to the shell is the line. A new-line character is thus normally of syntactic significance, although it may be escaped with a `\e' as described below. The most fundamental delimiters for the shell are the blank and the tab character, generated by a control-i. There are also a number of characters which have special significance as they define tokens which are part of the command language of the shell: `>' and `<' which denote input and output redirection, `(' and `)' which are used to delimit command lists, `;' which is used to separate commands for sequential execution, and `|' and `^' which are completely equivalent ways of specifying a .it pipe in a .it pipeline. The ways in which these are used in construction of shell commands will be discussed in the next section. .s3 At the syntactic level, there is also a .it "parameter substitution" facility, which can be used to substitute variables. Parameter substitution is introduced by the character `$' and has several different forms, each of which yields zero or more characters into the input stream replacing it. We describe each such construct in turn. .s3 .lp +22 20 $number Substitutes the number'th argument in the currently positioned argument list. The accessing of the argument will be described later. .s3 .lp +22 20 $* Substitutes all arguments in the current argument list, starting at the first `$1'; successive arguments are separated by blanks. .s3 .lp +22 20 $name .lp +22 20 ${name} Substitutes the value of the shell variable .it name. The second form can be used when this construct is immediately followed by a letter. .s3 .lp +22 20 $$ Equivalent to `${pid}'. .s3 .lp +22 20 ${name?str1:str2} Substitutes .it str1 if name is set else substitutes .it str2. Currently only quoting with `\e' works correctly within .it str1 and .it str2. In particular, `$' constructs and quoting via `\'' and `"' within these strings is unreliable as it is badly implemented. .s3 .lp +22 20 ${name:default} Substitutes the value of .it name if this variable is set, else substitutes the string .it default. .s3 .lp +22 20 ${name?str} Substitutes the string .it str if the variable .it name is set, else substitutes nothing. .i0 .s3 Whenever a paramter is being substituted a slightly different effect occurs if the `$' is immediately followed by a `.'. In this case, any substitution from parameters trims suffices from the parameter. Thus if `$0' gives `a.out', then `$.0' will give `a', and if `$prog' would give `foo.p' then `$.prog' would give `foo'. Also if the `$' character is not followed by any character described above then that character is returned. .s3 It is possible to .it quote special characters to prevent their special meaning. Before describing the various ways to do this, we should note that the characters `[', `*' and `?' have special meaning in command contexts where they cause .it "filename expansion," a kind of pattern matching of an lexical token against file names. These characters also often need to be quoted. The most simple kind of quoting is that with the character `\e', thus `\e>' is the same as the character `>', but will not be recognized as a syntactic metacharacter for output file redirection. There is a way to quote longer strings using either the delimiter `\'' or `"'. Thus the construct: .dt .s3 echo "*** NOTES ***" .s3 could be used to prevent the spaces and `*'s from having their special meaning. It should be noted that no quoting, expansion or substitution of any kind occurs within `\''s or `"'s, and that the quoting must terminate before an end of line. It is also possible in the shell to escape the newline character with a `\e', this causing the newline to be effectively replaced by a blank. .s3 .bd "Syntactic structure." The syntactic structure of the input to .it sh is essentially the same as that to .it sh (I). The fundamental component of a command is a .it pipeline, which consists of one or more commands separated by the character `|' or `^', with the separator optionally followed by the character `*', i.e. `|*' or `^*'. Each command in the pipeline has its standard output connected to the standard input of the next. The forms with the character `*' cause the diagnostic output to go through the pipe with the standard output. .s3 More than one pipeline may be given on a single line if they are separated by the sequential execution separator `;'. The separator `&' termiates such a list of commands and causes the entire list to be executed without waiting for termination. The variable .it pcs is set to the process id of the shell co-ordinating the execution of the command list, and this number is typed on the shells diagnostic output. When the command terminates, .it pcs is .it unset. Note that the command .s3 date ; echo boo & .s3 is thus equivalent to .s3 (date ; echo boo) & .s3 rather than like .s3 date ; (echo boo&) .s3 as it is in .it sh (I). .s3 Finally, the basic commands are composed of a command name and a list of (zero or more) arguments. There may also be input or output redirection specifiers of the form `<', `>' or `>>', possibly followed by `*', and then a parameter specifying a file name. The `*' here, as in the pipe specifiers above, specifies that diagnostic output is to be redirected with standard output (and is thus not allowed with `<'.) The form `< name' causes the standard input to be taken from the file .it name, which is first subjected to .it "filename expansion" as described below if it contains any of the characters `*', `?' or `['. The form `> name' causes the standard output to be put in the file .it name which is created, or truncated to length zero before execution begins if it exists. The form `>> name' is like `> name' but output is put at the end of .it name if it already exists. It should be noted that when a pipeline is executed in the background, the first element of the pipeline will take input from .it /dev/null unless the input is otherwise redirected. .s3 A final syntactic structuring is provided by parentheses `(' and `)'. A command may be given as a ny of the forms given above thus enclosed and participate in a pipeline. Thus, .s3 (date; time; echo "***") | lpr .s3 executes the commands .it date, .it time, and echoes the character string `***' to the line printer daemon .it lpr. .s3 .bd "Command execution." When a command is to be executed, the shell first examines the command name to see if it is a name of a built-in command. If it is not, then the shell will see if the name is actually an .it alias of another name. If it is, then the process starts over again, wiht the command name replaced by its .it alias. This process of alternately checking for built-in commands and for aliases will continue up to 100 times to allow multiple aliases. If this process terminates with the recognition of a built-in command then that command will be performed. If not, then the shell will attempt to find the resulting command in the directories in its search path as defined by the value of the variable .it path. This variable consists of a sequence of directory names separated by the character `\-'. The default value for .it path is `\-/bin\-/usr/bin' where here the initial `\-' signals that the first directory to be searched is `.', which is the same as the null string. After this, we are to search the directories `/bin' and `/usr/bin' for commands. If the variable .it path is not set, then the value `\-' is assumed, causing only the current directory to be searched. If the given command name includes the character `/', then it will be executed if and only if the path includes a null directory specification, and never from other prefixes in the path. Thus even if there is a `/bin/bin/date', `bin/date' will not find it with the default path. If the command name contains `*', '?' or `[', then it will undergo .it "filename expansion" as described below and will be interpreted only relative to the current directory or as a full path name. .s3 There is a general process of .it "filename expansion" applied to the arguments to the command. In this process the characters `*', `?' and `[' have special meaning. The character `*' will match any sequence of characters in a file name, the character `?' any single character, and the construct `[chars]' will match any of the characters in .it chars with the construct `x\-y' within chars standing for all characters between and including `x' and `y'. This process applies to arbitrary path names, and is subject to two restrictions. First, each `/' in such a path name must appear explicitly in the pattern \- `/'s are never matched by `*', `/' or a `[' construct. Similarly, if the first character of a file name is the character `.', it must be matched explicitly with a character `.' in the pattern. If, during command argument expansion, some arguments specify filename expansion, but none of these arguments matches any file name, then a diagnostic ``No match'' will be given and the command will be suppressed. .s3 A special variant of this filename substitution occurs in input redirect filenames, command names, and arguments to the built-in command .it chdir. Here the expansion must result in exactly one filename or a diagnostic will be printed indicating that the given pattern is ``Ambiguous''. .s3 If the shell finds a file which is executable but is not recognized by the system as an object file, then it will be examined to see if it is appropriate to be used as a shell script or by one of the interpreters the shell knows about. If the first word of the file contains the magic number of one of the interpreters, e.g. 0404 octal for the Pascal interpreter .it px (VI), then this interpreter will be forked with the arguments shifted to the right, the name of the file becoming the first argument. If the first word of the file does not indicate any of the interpreters, yet contains \s-2ASCII\s0 characters then a shell will be invoked as an interpreter. The path name for this shell may be specified using the .it shell variable. .s3 When a command terminates, if it terminates abnormally, a message will be printed indicating the cause of abnormal termination. If the command was not the one being waited for, i.e. if a background process started with `&' terminates abnormally, its process number will also be given. Finally, a time statistics line may be printed at command termination. This is described with the .it time variable below. .s3 .bd "Predefined and special variables." The following variables have special meaning to the shell and affect its behavior or are set as side effects of various commands. .s3 .lp +15 12 home Set to the users home directory as given in the .it htmp data base. Usually the directory where the user logs in, this is the default destination for a .it chdir command. .s3 .lp +15 12 nargs Maintained as the number of arguments in the current argument list. .s3 .lp +15 12 nice If given a numeric value, each executed command will be .it niced to this priority immediately before execution. .s3 .lp +15 12 path Specifies the search path for command executions as described above. .s3 .lp +15 12 pcs The process number of the last command started with `&'. Unset when this command completes. .s3 .lp +15 12 pid The process number of the shell; used in `$$'. .s3 .lp +15 12 prompt The prompt which preceded each command line interactively. If the shell is not interactive, then this variable is not set. .s3 .lp +15 12 shell The shell which is the default interpreter for executable files not recognized by the system. Defaults to `/usr/pascal/sh', the current home of .it sh. .s3 .lp +15 12 time When set, causes a command statistic line to be given following each executed command. This line includes the number of user cpu seconds, system cpu seconds, real time in hours minutes and seconds, and the machine utilization over this period expressed as a percentage. If given a numeric value, statistics will be given only for commands requiring more than this many total cpu seconds. .i0 .s3 .bd "Start up processing." When a new shell is created it first sets the .it home variable from the .it htmp database, initializes the .it prompt, .it shell, and .it pid variables and sets up any default aliases and interpreters. (Current default \fIalias\fR is ``time'' for ``tyme'', interpreter is ``/bin/px'' on value 0404.) The shell then process the command line arguments as follows: .s3 .lp +7 5 \fB\-V\fR Causes the shell to be .it verbose like \fB\-v\fR, but even when processing the startup files, e.g. .it \&.profile. .s3 .lp +7 5 \fB\-v\fR Causes the shell to be verbose; command input is echoed to the output with indication of the arguments which were substituted for parameters with the `$' mechanisms; such substitutions are bracketed with `[' and `]' for visibility. .s3 .lp +7 5 \fB\-c\fR Causes the shell to take as input the contents of the immediately following string. .s3 .lp +7 5 \fB\-t\fR Causes the shell to read exactly one line of input from its standard input. .s3 .lp +7 5 \fB\-i\fR Causes the shell to be interactive: the remaining arguments are \fInot\fR interpreted as a file to be executed and parameters, and the shell ignores interrupts and quits and prompts for input. Shells which have standard input and output teletypes also are interactive in the sense that they ignore interrupts and quits. .i0 .s3 If either the .bd \-c or .bd \-t flag is given, then the shell does not prompt, i.e. .it prompt is unset. If none of the \fB\-c\fR, \fB\-i\fR, or \fB\-t\fR flags are given, then the first argument argument is taken to be the name of a file containing commands to be executed. This argument becomes available as the 0'th parameter during interpretation, i.e. `$0'. Its value is immune to .it shift and .it rewind operations. The remaining arguments become the positional parameters, `$1', `$2', etc. The number of such positional parameters will be given by the variable .it nargs. These parameters may be manipulated by .it rewind and .it shift and given new values by .it set. .s3 After setting up all of this, the shell will read commands from the file .it \&.profile in the user's home directory. This file is typically used to set aliases and variables that the user wishes and also to change the value of .it path. If the shell is a login shell, defined as having been invoked with a name which started with `\-', the shell will then read commands from the file `.login' in the same directory. Shells normally terminate when they receive an end-of-file from their standard input; login shells will print ``logout'' when this occurs and execute the commands from the file `.logout' in the home directory. The home directory for the purpose of finding `.logout' is independent of the current value of the variable .it home. .s3 .bd "Built-in commands." The following commands are built into the shell. Input and output redirections have no effect on these commands, and are not allowed. Note also that since the command .it if (I) is not done within the shell, it cannot, in general, be used to qualify a built-in command. In general, therefore, the shell control structure must be used like \s-2FORTRAN\-II\s0 with only .it goto (I) commands on .it if (I) commands. .s3 .lp +12 10 abort Terminate abnormally. Useful only for shell debugging or fits of frenzy. .s3 .lp +12 10 alias Specify an alias for a command. When given two arguments the first argument is given alias the second argument. When given one argument the alias for that argument will be given. When given no arguments all aliases are given. .s3 .lp +12 10 chdir Change directory. If no argument is given change to the directory in the variable .it home. The argument may contain the metacharacters `*', `?' and `[' which are interpreted as for executed commands. This is the only built-in function which takes such arguments. .s3 .lp +12 10 interp Specify interpreters. Same as .it alias except that the first argument is the value of the first word of a file for this interpreter, i.e. its magic number, and the second is the name of the interpreter. .s3 .lp +12 10 logout Same as a control-d. .s3 .lp +12 10 noquit Causes the shell to ignore \s-2QUIT\s0 signals. This is the default. .s3 .lp +12 10 quit Causes the shell to not ignore \s-2QUIT\s0 signals for the purposes of debugging. .s3 .lp +12 10 rewind Causes the shell to reset the argument list to the state at entry, reversing the effect of all .it shifts. .s3 .lp +12 10 set Give one or more variables or parameters new values. With no arguments types the names and values of all variables. The simples kind of set is to set a variable `on', i.e. to the null string. To do this you can just mention its name, i.e. .s3 set time .s3 It is also possible to give variables string values by specifying the value after an `=', thus .s3 set time= prompt="+ " .s3 sets .it time in the same was as the previous example, and also changes the .it prompt. Finally, it is possible to do arithmetic in the .it set command. Operators available are `+=', `\-=', `*=', `/=', `|=', `&=', `%=', `=', `++' and `\-\-'. Thus .s3 set i++ j*=$i .s3 increments the value of variable .it i and then multiples the value of the variable .it j by the value of the variable .it i. Note that the operators `|' and `&' must be quoted, i.e.: .s3 set i\e|=1 .s3 to make the value of .it i be odd. One final operator is `@' which is equivalent to an .it unset. All of these operators except `@' may be applied to parameters, e.g.: .s3 set 0=a.out 1=$.1 .s3 .lp +12 10 shift Causes the argument list to be right shifted, argument 2 becoming argument 1, etc. May be given a count, possibly negative, for multiple right or left shifts, i.e. `shift \-1' for a left shift. .s3 .lp +12 10 tyme An internal version of \fItime\fR corresponding to ``set time'' for the course of the command. Does not work correctly for `&' processes. Note that \fItime\fR is aliased to .it tyme by default. .s3 .lp +12 10 unalias Given a parameter, removes that alias from the list of aliases. .s3 .lp +12 10 uninterp Like unalias for interpreters, takes the magic number and removes the corresponding entry. .s3 .lp +12 10 unset Removes the specified variables. .s3 .lp +12 10 wait Wait for all processes to terminate, or for the specified process to terminate. .it Wait may be aborted with an \s-2INTERRUPT\s0. .s3 .lp +12 10 : Label marker for .it goto targets. .i0 .sh FILES .dt /etc/htmp home directory data base .br /etc/passwd home directory data when not in \fIhtmp\fR .br \&.login start-up for login shells .br \&.logout prologue for login shells .br \&.profile beginning script for all shells .br /dev/null source of end-of-file .sh SEE\ ALSO sh (I), chdir (I), chdir (II), if (I), goto (I) .sh AUTHOR William N. Joy .sh BUGS As this is an experimental shell, there are probably several. Mostly, the design has a lot of rough edges and the new features don't always ``like'' each other. Some of them can't be successfully mixed.