CommanderDoc.tioga
Copyright Ó 1989, 1990, 1991, 1992 by Xerox Corporation. All rights reserved.
Michael Plass, September 30, 1992 2:46 pm PDT
Chauser, September 13, 1991 3:46 pm PDT
Christian Jacobi, July 21, 1992 5:43 pm PDT
Based on CommandToolDoc.tioga:
Copyright Ó 1985, 1987, 1989 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) May 28, 1985 1:05:55 pm PDT
Mike Spreitzer July 16, 1987 1:12:25 pm PDT
Last changed by Pavel on December 7, 1987 5:18:35 pm PST
Last Edited by: Gasbarro February 5, 1988 11:59:12 am PST
Bloomenthal, March 24, 1988 2:58:35 pm PST
THE CEDAR COMMANDER
THE CEDAR COMMANDER
CEDAR 10.1 — FOR INTERNAL XEROX USE ONLY
CEDAR 10.1 — FOR INTERNAL XEROX USE ONLY
Cedar Commander

©
Copyright 1984, 1985, 1987, 1989, 1990, 1991, 1992 Xerox Corporation. All rights reserved.
Abstract: This document is a user's guide for the Commander in Cedar 10.1.
Maintained by: Michael Plass:PARC:Xerox
XEROX  Xerox Corporation
   Palo Alto Research Center
   3333 Coyote Hill Road
   Palo Alto, California 94304

For Internal Xerox Use Only
News
Changes      (September 30, 1992)
* Changed the PackageIt.cm script to allow the second argument to contain spaces and special characters, provided it is appropriately quoted.
Example:
% PackageIt Kilroy "echo \"Kilroy was here\" >/tmp/xx; date >>/tmp/xx"
Changes      (July 23, 1992)
* The read-eval-print loop has been made more robust concerning IO errors on the commander's streams. This makes it OK, for instance, to destroy a CommanderViewer that is still initializing - previously, this would lead to an uncaught error.
Changes      (July 21, 1992)
* New commands IfProcExported and IfProcNotExported.
Bug fix      (July 14, 1992)
* Parameter substitution for the alias command had a bug, which has been fixed.
Changes      (June 23, 1992)
* The initial commander has had, for a while now, an heretofore-undocumented feature whereby the presence of a non-empty value for the environment variable COMMANDER←INITIAL←PERSIST will prevent the world from exiting when end-of-file is encountered on the standard input. The change is to not print the "Exiting ..." message in this case. The farewell message was also changed to be "Exiting Initial Commander".
Changes      (April 15, 1992)
* When the Run command is used with the -a switch (which means run again even if already run), the "Re-export" messages are no longer printed.
* New "Prop" command - allows property values to be fetched with default values and control over quoting.
* Substitution now applies to redirection targets as well as to other parts of the command line. For example, the command "Echo Hello >$outfile" is a useful thing to say.
Changes      (April 10, 1992)
* Added PrintFileProperties and SetFileProperties commands; changed PackageIt.cm to use SetFileProperties (instead of chmod).
Changes      (March 19, 1992)
* The Version command now prints just the version number without extra text around it; the default is to print major and minor version numbers; an integer argument may be used to specify how many components are desired.
Changes      (February 13, 1992)
* Changed the LoadedFiles command to rely on information recorded by the Run command; this should result in faster and more reliable PackageIt behavior.
Changes      (January 24, 1992)
* Alias parsing of tokens is now more consistent with other token parsing in the commander.
Changes      (September 13, 1991)
* CommanderOnStandardStreamsImpl registers interest in UnixTM SIGINT signal, with the result that CTRL-C typed in the standard streams commander produces an ABORT signal in that process.
Changes      (March 15, 1991)
* New Packaging facility; from PackageIt.cm:
Example:
dyload a RawViewers world (e.g. CedarCommander RawViewers)
...
% cd bindir -- The place where you want the package to end up.
% PackageIt RV RawViewers
% sh1 ./RV.ld
( The RawViewers initial command does a few things (like CommandsFromProfile ...) that are not captured by the checkpointing process ).
This will create the UnixTM executable named bindir/RV
* New command (in support of PackageIt, but generally useful):
ReadTo ReadTo <string> - Copy stdin to stdout until a line with just <string> is encountered.
* Fixed this doc string:
PrefixLines PrefixLines <string> - prefix each line of stdin with <string>
* New options to LoadedFiles (again in support of PackageIt):
LoadedFiles Format load state for restart
Usage: LoadedFiles [-pcr | -command | -names | -ccode | -libs] [-first <pattern>] [-after <pattern>] [-before <pattern>] [-last <pattern>] [-except <pattern>]
Changes      (November 5, 1990)
* The Files command won't descend into "hidden" directories unless asked.
* New Dirs command:
Dirs List directories matching given pattern(s)
switches:
-a include files like .* and *~
-f full name always (otherwise strips working directory)
-r recursive - delve into subdirectories
-s slow - don't use heuristics to guess which might be subdirectories
Changes      (October 18, 1990)
* The CD and Push commands now check for the existence of the directory.
* The CD and Push commands now allow star patterns (requiring a unique match).
* New CDH and PushH commands; are relative to the home directory.
* New CDF command; does not demand that the directory exists.
* The Type command now does star expansion.
* The Type command also has a synonym, namely Cat. (I've invoked the Catalog command more times than I like to think about).
* New Files command:
Files List files matching given pattern(s)
switches:
-a include files like .* and *~
-f full name always (otherwise strips working directory)
-r recursive - delve into subdirectories
-s slow - don't use heuristics to guess which might be subdirectories
This is especially useful for dealing with commands that do not do star expansion, e.g.,
Bringover $(files /PCedar/Top/Imager*.df)
The recursive mode does not work quite as I would like it to; the pattern must match the subdirectories as well as the files. For instance "files /PCedar/*" works OK to list all the files in PCedar (it took about six munutes yesterday), but "files /PCedar/*.mesa" would not find all the mesa sources. I plan to fix this someday.
New Commands      (April 16, 1990)
BackgroundPriority Execute rest of command line at background priority
ForegroundPriority Execute rest of command line at foreground priority
NormalPriority Execute rest of command line at normal priority
Changes      (April 12, 1990)
* The Quit command is decomissioned (it tells you what to do instead).
* The Fail command now returns its argument as the message.
* New command ERROR (raises an unnamed ERROR).
Bug fixes      (April 12, 1990)
* Printing of command messages has been reorganized; messages should no longer ever drop into the bit bucket.
Changes      (March 27, 1990)
* New commands: IfInstalled, IfNotInstalled, WhenInstalled
* Some minor bugs fixed.
* Rearranged history logic so Redo command can be fixed to do the right thing.
Bug fixes:       (March 13, 1990)
* ambiguous commands now fail properly in the PreRegister step
* HistoryLog, Statistics, Terse, and Verbose commands now set the control bits in the proper commander instances (in particular, you can now use these in the initialization entries in your profile, and have them take effect).
Other changes:      (March 13, 1990)
* Initial value of keepHistory changed to TRUE.
* Input stream is now Reset on abort.
Changes      (February 12, 1990)
* Interface changes to CommanderBackdoor.
* New commands: Statistics, HistoryLog.
* STOP! made more robust.
* New (private) CommanderSys interface to isolate PCedar/DCedar differences.
The UnixTM environment variable COMMANDER←INITIAL𡤌OMMAND is used to pass the initial command to CommanderOnStandardStreamsImpl. 
      (February 1, 1990)
Command tokens may be quoted with balanced parens, in places where double quotes were allowed (double quotes are OK, too). Shades of JaM! 
      (February 1, 1990)
$foo substitution now also gets UnixTM environment variables. 
      (February 1, 1990)
Some new commands: 
Command do command-line as a command
Commander Make a nested commander
CommanderViewer Create a new Commander Viewer (rest of command line is the initial command)
CommandsFromProfile Execute commands from a user profile entry
      (February 1, 1990)
The Run command knows about the XR←run convention, for the sake of c programs. 
      (January 30, 1990)
Switched to ".command" and ".require" files (see details below)  (January 24, 1990)
The Commander implementation now puts /PCedar/Commands/ in the search rules; it is recommended that DF files in the release SModel the .command and .cm files directly into [PCedar2.0]<Commands>, and that the load files use the From command to indicate installation directories; thus you won't need to Bringover packages to use them.   (January 24, 1990)
PseudoCheckpoint now sets execute permission on the rollback script, and also captures prefix map state.        (January 24, 1990)
CD with no arguments now gets you into your UnixTM home directory. (This may change, subject to expressed opinions).  (January 12, 1990)
Arguments for command files now work, and the $CommandFileDirectory property is set. 
  (January 12, 1990)
The "From" command no longer requires a terminating slash on the directory argument; also, relative directories are now OK.  (January 12, 1990)
Command abbreviation implementation is improved.  (January 12, 1990)
MkDir and RmDir commands are now provided.  (January 9, 1990)
A new command, LoadedFiles, is provided to reformat load-state infromation in various useful ways. This is used in a command file, PseudoCheckpoint.cm, to provide a means of capturing a version-bound description of a running world.  (January 9, 1990)
The section on "Installation" was added to the end of this document.   (January 9, 1990)
See Also
CommanderCommandsDoc.tioga
Introduction
General
The Commander is a stream-oriented command-line processor. It bears similarities to the UnixTM shells, the Alto executive, the Tajo Executive, etc. It is a means for invoking registered commands with arguments.
Getting started
If you are running on Viewers, you will notice that a Commander viewer appears with a herald that contains the current working directory of that command tool; more will be said about this later about the working directory. The Commander will have printed a prompt (initially "% ") and will be waiting for input.
The menu of a Commander initially has three buttons, STOP!, Find, and Split. Find, and Split work the same way that the other Find, and Split buttons in Cedar work. The STOP! button attemps to stop whatever is the current command running in the Commander viewer. It does this by raising the signal ABORTED in the Commander process. Usually this will result in the string " -- Aborted" being printed along with a new Commander prompt.
A Commander read-eval-printer may also be started up given simply an input and an output stream; the very first instance is started up using the standard in & out streams provided by PCR, and this is used to load up the rest of the system (often including Viewers and Tioga). The UnixTM environment variable CEDAR←INITIAL𡤌OMMAND is used to pass the initial command to this standard-stream Commander.
Command documentation
Documentation for individual commands is in the file
CommanderCommandsDoc.tioga
Facilities overview
In general, the Commander interprets each "line" of input as a separate command. The first token on the command line is taken to be the name of a command previously registered with Cedar. The rest of the command line is taken to be arguments to that command or directives to the Commander.
It is possible to type several logical command lines on the same input line and it is possbile for the first thing on the command line to be the name of a command file, rather than itself be a registered command.
The rest of this section contains a brief list of the facilities provided by the Commander. Each facility will be described in more detail later.
Command Files
Command files are executed by creating a new, nested, instance of the Commander which reads from the given file rather than from the keyboard. Generally command files are files named Mumble.cm and they may be executed by just typing "Mumble" on the command line or by typing "Source Mumble.cm". Command files can have arguments, as described later.
IO redirection and pipes
Commands are given a standard input stream and a standard output stream for their use. Normally, these streams are attached to the Commander viewer, but they may be redirected to read from or write to files. For example, the command line Date > date.txt will put the date and time into the file date.txt.
It is possible to "pipe" the output of one command into the input of another by use of the syntax commandA | commandB. For example, the command line Date | Indent 10 will print the date and time in the Commander viewer indented by 10 spaces.
Howerver, since most commands do not use the "standard" input, you may find piping to be of limited utility.
Star expansion
No automatic star expansion is done, since for all but the very simplest commands, the file name patterns can get confused with the other syntax. Many commands do expand file name patterns.
Related commands
There can be multiple commands on the same command line, separated by ';. If one of the earlier commands "Fails" (see below), later commands are not executed. An example multiple command is:
Date; Echo Hello
which prints out something like:

%
Date; Echo Hello
December 15, 1989 10:20:19 am PST
Hello
%
Command Environment
The Commander makes an attempt to set up interesting execution environments for commands. One of the most interesting properties the Commander can set is $WorkingDirectory, which governs the directory in which to lookup short file names.
File name completion
Currently not implemented.
As in all Cedar typescript-based programs, hitting the ESC key in response to a prompt brings up the last line of input you gave to the tool. This can be handy for repeating the previous command, either exactly as before or somewhat edited, however you wish. If you type ESC after you've already given some of the input line, normally nothing happens.
However, if you include the following line in your User Profile:
Commander.DoCompletion: TRUE
then the ESC key performs file name completion when typed after other input.
Completion works by looking at the last space-separated ``word'' on the line so far and enumerating all files (relative to the current working directory) that begin with that prefix. If there's only one such, the prefix is replaced by the complete name of the file. If no such files exist, the Command Tool viewer is blinked. If there is more than one file with that prefix, then the prefix is completed as much as possible. If no amount of completion is possible, a viewer is created containing the names of the files that match the prefix. If you include the line:
Commander.PossibilitiesViewer: FALSE
in your User Profile then this feature is disabled and the line remains unchanged. With this facility, most file names can be typed in a small fraction of the number of keystrokes and with fewer spelling errors.
A slightly esoteric use of the completion facility concerns the use of *'s in the prefix. When the prefix is a name pattern, all files matching the pattern are considered for completion. This allows you to avoid the creation of the possibilities viewer when you know something more about the file name than the prefix. For example, suppose that your local directory contains these files:
OtherCommandsImpl.bcd
OtherCommandsImpl.errlog
OtherCommandsImpl.mesa
Then when you type
open oth<ESC>
to the Command Tool, it will complete this to
open OtherCommandsImpl.
and pop up a viewer containing the three names. If, however, you already knew that these three files were the possibilities (you're simply using the completion facility to saving typing), then you could instead type
open oth*.m<ESC>
and the Command Tool would complete it to
open OtherCommandsImpl.mesa
as you presumably desired.
What to do if it breaks
Most commands intended for use with the Commander catch signals that could reasonably be expected to arise. Uncaught errors are intercepted by the Commander, and you will be asked whether you want to debug or not. If you sat "n" the command will be aborted, whereas if you say "y", you will be left to the mercy of whatever debugger you have available.
The value of the $DebugUNCAUGHT property may be used to supply the answer rather than using a prompt; the may me desirable when the standard input is not a place the user can type, or when there is a reliable local debugger available. To use this feature, say
SetProperty DebugUNCAUGHT "y"
or
SetProperty DebugUNCAUGHT "n"
If a command runs away, try clicking the STOP! button in the Commander from which the command was started. This is not completely reliable because it uses Process.Abort to squelch the command. It is possible for a command to ignore this signal, although commands should check for this signal by periodically executing Process.CheckForAbort[]. As we find out which commands cannot be stopped, we can fix them.
For programmers: Process.Abort raises ABORTED in the command's process. This won't work if the command has FORKED, or if it never waits on a condition variable which has aborts enabled. A command can explicitly check for ABORTED by calling Process.CheckForAbort and command implementors are encouraged to do so at appropriate intervals.
Command model
What is a command?
Simply speaking, a command is any action implemented by a procedure registered via Commander.Register. The command registry contains the mapping between the names of commands and the CommandProcs which do the work. For example, when you type "Date<CR>" to the Commander, the procedure "Date", of type Commander.CommandProc, in the module InitialCommandsImpl.mesa is called. This procedure obtains the current date from the BasicTime interface and prints it using the facilities of the IO package.
There are a few things that the Commander recognizes that are not in the Commander registry. The Commander provides two facilities that make life a bit easier. One is the ability to type a name which corresponds to some Commander.CommandProc that is not yet loaded into the running copy of Cedar. The other is the ability to type the name of a command file.
When the Commander encounters a name, say Mumble, that is not in the registry, it first tries to locate a ".load" file named Mumble.load, or a command file named Mumble.cm.. If this finds Mumble.load, then the Commander assumes that you have typed the name of a command that is not yet loaded. The Commander will first load the necessary software into Cedar (by executing Mumble.load as a command file) and then call the CommandProc. During the execution of Mumble.load, the working directory will be initialized to the one where Mumble.load was found. If a .load file cannot be found, then the Commander will try to locate a command file named Mumble or Mumble.cm. Each command in the command file will be run. More exact rules are given later in this document.
Therefore, as recognized by the Commander, a command is either a registered procedure, a "load" file that will register a procedure, or the name of a command file which contains other commands.
Command view of the world
When a CommandProc runs (usually as a consequence of a typed command), it receives an environment in which to run. The CommandProc is free to change or ignore this environment, but most do not.
The key elements of this environment are the standard input and output streams, the working directory, and other properties.
The standard input stream is usually connected to the keyboard, but may sometimes read from a file. The standard output stream is usually connected to the display, but may sometimes print to a file. (The Commander can even connect the output of one command to the input of another. This is called a pipe.)
The Cedar file system is called FS. FS provides a hierarchical directory system, as well as caching for remote files. As in other systems of this type, the full path name of a file can become quite long. The working directory facility provides a way for users to most of the time use short file names without losing the advantages of the hierarchical directory system. Most programs need not even be aware of the working directory, as it does not need to be explicitly mentioned. (However, the working directory will not propagate across a FORK without special attention, so be a little cautious.)
Command lookup
When a command name is presented to the Commander it can denote quite a range of possible actual commands. Searching is affected by the search rules (see the documentation for the AddSearchRules, SetSearchRules and PrintSearchRules commands), the command registration, and the exactness of the match. The intention is to find the "closest" command first, where a more exact match is closer than a less exact match, and a match earlier in the search order is closer than a match later in the search order. A command is searched for according to the following rules:
1. The first exact match found will be used.
A. Search the registered commands. Commands are registered in a flat name space (unlike the Cedar7.0 and earlier CommandTool).
B. Search for load files (*.load) or command files (*.cm) in search rule order. So if the search rules are (///2.0/Commands/ ///2.0/System/), then ///2.0/Commands/Sample.cm will be found before ///2.0/System/Sample.load, but ///2.0/Commands/Sample.load will be found before ///2.0/Commands/Sample.cm. The current working directory is alway implicitly at the front of the search rules.
2. If there is no exact match, then we search for an match using the given name as a prefix. All prefixes are accumulated before execution, and the command will only be executed if there is a unique short name (per search rule element) in the accumulated names. For this pass, the case of the names is ignored, even if the underlying file system has case-sensitive names.
A. Search the registered commands in search rule order.
B. Search for load files (*.load) or command files (*.cm) in search rule order.
If there is no exact or unambiguous match, then the ambiguity will be indicated. For example:

% a
a ambiguous: Abort AddSearchRules Alias Aliases
PreRegister a failed to register command
%
If there is an unexact, unambiguous match, then the "PreRegister" command provides the full name as its result . For example (with command trace enabled):

% pw
*** PreRegister pw
*** pw
*** PWD
/usr/Build/

% ? pw*
*** ? pw*
PWD Print Working Directory
%
Recommended command line syntax
Most commands take a sequence of swtches and file (or directory) specifications, parsed from left to right. A switch starts with a '- character, and typically is a one character specification of some option. Documentation provided with the command should give a summary of what the switches do. For example, the documentation for the SModel command is:

SModel
dfFile*
Stores files under control of the given DF files.
-c  check remote {default}
-n don't store
-t touchy (warnings cause failure)
-u reset switches to default values
To execute the SModel command on two DF files, using the -n switch for the second, the command might look like:
SModel file1 -n file2
The switches should usually be sticky, in that once a switch is set it remains set that way for the remainder of the files in that execution of the command, although the defaults are used for the next execution of the command.
The '~ character is recommended as a means of inverting the sense of a switch. For example, to execute the SModel command on two DF files, using the -n switch for the first but not the second, the command might look like:
SModel -n file1 -~n file2
Working directory
Each Commander maintains a working directory, which is shown in the herald of the Commander viewer. The working directory is changed by the command CD.
Every command run from a Commander acquires the working directory. Generally, anytime one of the commands uses PFS and passes a shortName (a file name with no absolute directory specification), PFS will look for the file in the working directory.
CreateButton Open Open $FileNameSelection$ is a very handy command. It puts up an open button that uses the working directory of the Commander in whose herald it is.
Examples
Sit down in front of a Cedar workstation and follow along. Try variations as they occur to you. First click the "Cmd" button in the upper right to get a Commander, if there isn't one already.
Simple commands and output redirection
The date command prints the date and time on the standard output. The Open command creates a viewer on a given file. The Version command prints the version number of the running Cedar on the standard output.
Type Date:

%
Date
December 18, 1989 12:27:51 pm PST
%
Now try redirecting the ouput of the date command:
% Date > date.txt
where blanks are required both before and after ">".
The standard output from date has been directed into the file "date.txt" whose previous contents, if any, are destroyed. Take a look in date.txt:
% Open date.txt
Destroy the date.txt window. Incidently, output from a command can also be appended to a file:
% Version >> date.txt
% Open date.txt
where blanks are required both before and after ">>".
Semicolon: running multiple commands on a line
It is possible to run several commands on the same command line by separating them with semicolons:
% Date;Date;Date
Monday, April 22, 1985 6:48 pm PST
Monday, April 22, 1985 6:48 pm PST
Monday, April 22, 1985 6:48 pm PST
Semicolon has another effect. The Commander has a notion that a command either succeeds or fails. A CommandProc that wishes to notify the Commander of failure returns a special value. Suppose that several commands are on the same command line separated by semicolons. If one of them "fails," later commands will not be run. There is a special command, called "Fail" that prints its arguments and returns the failure value. Incidently, Fail was implemented mostly to test the Commander! It doesn't have a secret use (but if we told you, it wouldn't be a secret, would it?).
% Date; Fail This Command Always Fails; Date
April 12, 1990 12:54:45 pm PDT
This Command Always Fails
Skipped: Date
Notice that the second Date command was not run. The message "Skipped: Date" was printed by the Commander.
Comments and uninterpreted commands
Some commands don't do anything. "-" and "--" are useful for commenting the Commander typescript and for putting comment lines in command files:
% -- now try the date command
% Date
Monday, April 22, 1985 6:48 pm PST
But remember that the Commander is not very smart about picking the command name out from the crowd! To be safe, include a space after the name of a command.
% --hello
[[--hello . . . not found]]
Normally, commands are interpreted. This means that the syntax of their command lines cannot conflict with the special command line syntax which is interpreted by the Commander. For example, the Commander places special interpretation on the semicolon and on the token ">". There is a way to mark certain commands as uninterpreted. In this case, the Commander does no command line interpretation, but passes everything up to the next carriage return to the command.
- and -- are uninterpreted commands. They are set up so that their command lines can include anything, including special characters like '; and '> without any effect.
% -- date ; date
Notice that the -- command extends to the end of line, not just up to the semicolon.
Commands that take commands as arguments
Some commands take commands as their arguments:
% Time Date
Saturday, November 26, 1983 3:45 pm
Running time: 00:00:00.070624
%
Look at the implementation of Time if you want to do something similar.
Filters, Pipes, and input redirection
A filter is a command which reads from the standard input and writes to the standard output. Indent is a filter. It reads each "line" (determined by carriage return) from the standard input, indents it by a certain number of spaces, and prints it to the standard output.
Remember that normally, the standard input comes from the keyboard. Start Indent and type for a while. Type DEL to stop it (indicated by {DEL} below). User typein is italicized:
% Indent 10
Now is the time
Now is the time
for all good men
for all good men
to come to the aid of
to come to the aid of
their party.
their party.
{DEL}
%
The standard input can be redirected to come from a file:
% Date > temp.txt
% Indent 10 < temp.txt
Saturday, November 26, 1983 4:37 pm
%
The same effect can be achieved without the temporary file by connecting the ouput of Date directly to the input of Indent with a pipe. Pipes are constructed with the character '|:
% Date | Indent 10
Saturday, November 26, 1983 4:39 pm
%
Properties
The Commander maintains a property list. This list is used by the implementation to store things like the Commander prompt string. The commands GetProperties and SetProperty can be used to examine and change properties:
% SetProperty $Prompt "Hello %l%%%l "
Hello %
The prompt is normally set to "%l%%%l ". The percent sign is doubled because the Commander uses IO.PutF to print the prompt and % is a special character to PutF and must be doubled to print correctly. The "double-quotes" are necessary so that the trailing space will be included in the value of $Prompt. The %l indicates where the bold (and normal) looks will be applied.
SetProperty only handles properties with ROPE values. The command GetProperties prints properties using PrintTV and will print any kind of property.
% SetProperty $Junk Stuff
% GetProp $Junk
commander properties:
$Junk = "Stuff"
%
The Commander provides a facility for command line access to the values of properties, using the special symbol "$". Only those properties with ROPE-valued values work this way. The command Echo is very handy for exploring this turf because all that it does is echo its own command line after processing by the Commander.
% Echo $Junk
Stuff
%
Quoting
A ROPE literal is interpreted according to the standard Cedar rules. For example:
% Echo a b
a b
% Echo "a b"
a b
% Echo "a \"b"
a "b
% Echo "a ""b"
a "b
% Echo "a \nb"
a
b
% Echo "a > b"
a > b
Command files
Simple command files
A command file is a text file containing commands. To run a command file, either:
1. Use the Source command, or
2. If the file's extension is ".cm", use the short name of the file.
Suppose that the command file test.cm contains "Date{CR}Version{CR}". Then:
% Source test
> Date
Saturday, November 26, 1983 5:13 pm
> Version
Cedar 5.0.101 of November 23, 1983 5:20 pm
The command Cmd creates a new Commander. When Cmd has no arguments, it creates a new Commander window. When Cmd has an argument, it is interpreted as the name of a command file. A new instance of the Commander is created, but it runs in the same window as the old Commander.
TouchyCmd is like Cmd, except that if any of the commands in the command file fails, the execution of the command file is aborted.
When the Commander encounters a command name, it tries to locate a command file of that name and then acts as though the user had typed "Cmd commandFileName":
% test
> Date
Saturday, November 26, 1983 5:15 pm
> Version
Cedar 5.0.101 of November 23, 1983 5:20 pm
Command file arguments
However, command files can themselves have arguments. First consider the command Echo. Echo merely prints its own arguments and returns:
% Echo a b c
a b c
Inside a command file, the special syntax $n, where n is an integer, refers to the nth argument to the command file. Suppose that the command file Test.cm now contains "Echo $1 $2 $3{CR}":
% test a b c
> Echo $1 $2 $3
a b c
The idea is that it should not be obvious when a command is implemented by a CommandProc and when it is implemented by a command file.
Nested command files
Of course, command files will nest. Be cautious of infinite recursion, though; something may break in a nasty way.
Command line syntax
This section restates the command line syntax in a collected fashion.
The first token on the command line is interpreted as the name of the command. The first token is defined to be anything after the leading spaces and tabs are stripped away up to but not including the first character in the set {SP, TAB, CR, '|, '&, and ';}. The command is looked up in a database and found to be either "interpreted" or "uninterpreted."
The processing of the two types of commands are quite different from then on.
Uninterpreted Commands
The command line for an uninterpreted command extends from the character after the name up to (and includes) the first CR. The Commander makes no assumptions about the command line syntax of uninterpreted commands, except that the name of the command must be isolated by the same mechanism that finds the name of an interpreted command.
As a consequence of this strict view of "uninterpreted," uninterpreted commands cannot participate in many of the facilities described belo.
Interpreted Commands
The command line of an interpreted command is a string of tokens, some of which are interpreted specially by the command tool. Some of the tokens may participate in substitutions. After substitutions, special tokens are interpreted directly by the command processor. Remaining tokens are passed to the command as arguments.
Quoting
What looks like a Cedar ROPE literal is considered to be a single token consisting of the character sequence designed by that Cedar ROPE literal according to the usual rules.
Characters with special significance for the command processor ($;<|>) are relieved of their special significance when they occur inside a quoted string.
Substitutions: $
$name will be replaced by the value of the environment variable name. An environment variable is a name-value mapping maintained by the command processor and kept on a property list. Examples of environment variables are the current user and the working directory. Conversion to the atom which names the environment variable is made by the procedure Atom.MakeAtom[name]. The lookup will be made first on the Commander property list, then on the process properties list, and finally as a UnixTM environment variable. If no value exists or the value found is not a Rope.ROPE, then the string is left unchanged. Read on a little further if you need more control on value substitution.
$n (n an integer), when it occurs in the text of a command file, will be replaced by the nth argument to the command file; $0 gets the name of the command file (who says you can't get something for nothing?).
$(cmd arg ...), will execute "cmd arg ..." an a command, and substitute the output (after removing any trailing newline character).
For more control over property substitutions, the Prop command may be used in conjunction with this executable substitution syntax. In these terms, $foo is approximately equivalent to $(prop -s foo "$foo"); other particularly useful combinations are
$(prop myprop Unknown) - gets value of myprop, or the default value of "Unknown"
$(prop -f myprop) - fails if myprop is undefined or unprintable.
I/O Redirection: <, >, >>, |
> file directs the standard output of a command to file
>> file appends the standard output of a command to file
< file sets the standard input of a command to read from file
Note: ">" or ">>" or "<" must be preceded by whitespace.
commandA | commandB sets the standard output of commandA to connect to the standard input of commandB (pipe). CommandA will be started "in the background". If a command within a pipeline fails, subsequent commands receive EndOfFile on their inputs.
Terminating characters: ;, |
The semicolon ";" and vertical bar "|" serve to separate multiple commands, in addition to being commands in their own right. That is, the part of the command line to the left of a terminating character is executed as a command (with output directect to a pipe in the case of "|"), and the terminating character begins the next command.
The semicolon command executes its arguments as a command, unless the previous command failed. However, if it has no arguments, it quietly succeeds.
If a Commander.CommandProc returns the atom $Failure, it is deemed to have failed.
Example:

% Date; Fail; Date; Date;; Date
*** Date
December 15, 1989 11:57:08 am PST
*** ; Fail
*** Fail
This Command Always Fails
*** ; Date
Skipped: Date
*** ; Date
Skipped: Date
*** ;
*** ; Date
*** Date
December 15, 1989 11:57:08 am PST
%
The vertical bar command executes its arguments as a command, with standard input from the current pipe.
Command files
The first token on the command line may be the extensionless name of a command file with the extension ".cm". A new instance of the command processor is started, with input stream connected to the command file, but output and error streams connected to the original viewer. The new instance has the Commander property $CommandFileDirectory initialized to be the name of the directory where the command file was found.
Installation
This is based a message I sent out to PCedarUsers; it needs to be updated and reworded to sound less tenative.
Subject: Upcoming Commander changes.
To: PCedarUsers^
cc: Michael Plass
Reply-To: Michael Plass
This message is to give everyone fair warning of some upcoming changes in the PCedar commander that affect the way commands get registered, and the way progams are installed.
Yesterday after the PFUDGE meeting, a group of us gathered to decide a few details. This is what we came up with:
1. New names for .load and .install files:
To prevent confusion about partially-ported packages, and to ease source-sharing, we will change some file extensions:
.load --> .command
.install --> .require
2. New generic top-level name:
What I was calling /release will be called /PCedar
3. The Require command:
It is desireable to use the simplest collection of commands that we can get by with in .command and .require files; we would like to think of these as being written in a little language with well-defined semantics, so we can easily write programs for checking consistency. To this end, these files should ordinarily contain lines in one of these forms (here the <...> brackets are meta-symbols)
Require <world> <component> <resource>
<world> denotes what major collection of software we are talking about, i.e., PCedar, PCedarChest, DATools, etc. Typically, these will be generic names that get translated by the prefix map into the "current" place.
<component> designates the component, e.g., Imager, Tioga, etc.
<resource> names the resource that is needed from the component.
The initial implementation of this will CD to /<world>/<component>/, execute <resource>.require, record <resource> as supplied (provided no failure has occured), and restore the working directory; if <resource> was already supplied, the Require is a NOP.
Run <shortname>
Runs the named executable in the current working directory.
4. Other name changes:
I decided to leave the "Install" and "Installed" command names alone. "Install" does use the ".require" extension. (Under normal conditions, these commands will not be used directly, so names don't matter too much.)
5. From command:
will still be available, as a generally-useful command.
6. PreRegister
The PreLoad command will be renamed to PreRegister.
7. Synonym
This seems like a good time to change the name of the "Rose" command to the harder-to-type-but-easier-to-guess name of "Synonym"
8. Search rules
I would like to change things so that the CWD is not always searched first for the ".command" files; more often than not, I have found this to cause trouble. Opinions? Being able to place a late-bound "." in the search rules seems like a better idea, and is more consistent with Unix.
9. An example (assume Ó on all of these, please):
-- /PCedar2.0/BigCardinals/BigCardinals.require
Run BigCardinalsImpl
-- /PCedar2.0/Commands/Scheme.command
Require PCedar Scheme Scheme
-- /PCedar2.0/Scheme/Scheme.require
Require PCedar BigCardinals BigCardinals
Run SchemeSysPFSImpl
Run SchemePackage
-- Scheme-Source.df
...
Directory [PCedar2.0]<Commands>
Scheme.command
Directory [PCedar2.0]<Scheme>
Scheme.require
...
Michael.
On stable snapshots
Providing a stable snapshot of the world is something that I think is best done by means of a new PFS view (not yet implemented). The idea would be to have a program (akin to the version map builder) that would construct a file snapshoting the version numbers of the world by traversing the DF files, so that
pma /pcedar -stable:/net/palain/plass/PCedar2.0-89-Dec-19/STABLE
would use the contents of the file /net/palain/plass/PCedar2.0-89-Dec-19 to filter the view of the world. (Don't take the example too literally, this is by way of illustration.)
Portions of the world could be unfrozen by using longer paths. For example, if I want to run off the latest RawViewers and Imager, I might say:
pma /pcedar/imager -vux:/pseudo/pcedar2.0/imager
pma /pcedar/imagercolordisplay -vux:/pseudo/pcedar2.0/imagercolordisplay
pma /pcedar/rawviewers -vux:/pseudo/pcedar2.0/rawviewers
In short, prefix maps seem to be a wonderful abstraction for providing that extra level of indirection in just the right place.
More on stable snapshots
The PseudoCheckpoint command is an attempt to provide another way of making a stable world. It writes a .pcr and a .cm to restore the most interesting bits of state, and a "rollback" unixcommand to kick things off. Refer to /PCedar2.0/Commands/PseudoCheckpoint.cm to get an idea of how it happens, and what the limitations are.
Your comments are welcome.
Michael.