SECTION 6

exec_com

The exec_com command offers yet another means of abbreviating the typing involved in command invocation. With exee_com you can place frequently used command sequences in segments that are then processed by the invocation of the exec_com command. Plus it offers the feature of control statements, which permit more variety and control in the execution of command sequences. This procedure enables you to invoke a large number of commands with only one command and arguments.

This feature is made even more flexible by the inclusion of arguments to the command that can be substituted for special strings in the exec_com segment. By this means, and of course by including active functions as well, you can have the entire sequence of commands act on different input each time it is executed. And to deal with variations in the execution process that different input might necessitate, you have the advantage of control statements.

CREATING AN exec com SEGMENT

An exec_com segment is created with a text editor and can make use of any of the Multics command conventions. The entryname you assign the segment must have the suffix ec (e.g. print.ec).

To illustrate the creation and functioning of an exec_com segment, we will create a short, simple segment comprised only of commands, that is, without any control statements. To change your working directory, print it, and list its segments and your access to them, you would type in the following lines with a text editor such as qedx (described in Part 1):

tmpD9-1.gif

Argument Substitution

The ampersand character (&) and number used in the change_wdir command line refers to an optional argument that is substituted when the exec_com command is invoked, just as is done with the do command. The ampersand character is also used in exec_com to signify the start of a control statement; that will be discussed below. The particular values that are to be substituted are placed on the exec_com command line, as in the following:

! exec_com change.ec >udd>Training>Jones

When you are working with an exec_com segment that calls for more than one argument to be substituted, you arrange the arguments in sequence, separated by blank spaces, after the pathname argument on the command line. Let's suppose you have a segment named action.ec which requires three arguments. The command line used to execute this segment would look like the following:

! exec_com action.ec flower tree shrub

The three arguments - flower, tree, and shrub - would be substituted for ampersands and numbers in the following order:

tmpD9-2.gif

If the third argument were not supplied on the command line:

! exec_com action,ec flower tree

The space occupied by &3 would be left blank; the second argument "tree" would not be substituted in that space. If possible, the commands, active functions, and control statements will process without the missing arguments, but if they cannot, an error message will be returned. Often, but not always, the error message will tell you which part of the exec_com segment is not functioning.

There are also some special substitutions that can be made in exec_com segments. First of all, you can, if you wish, place the number of optional arguments supplied with a particular execution into the exec_com lines. In the action.ec segment used above, any position containing the figure &n would receive the number 3 before the segment was executed.

In another substitution you can place the entryname portion of the exec_com's pathname, without the ec suffix, into the exec_com segment. In the action.ec segment, any position containing the figure "&ec_name" would receive the entryname action before the segment was executed.

Lastly, you can place the directory name portion of the exec_com's pathname in the exec_com segment by using &ec_dir.

Control Statements

Control statements enable you to specify conditions for command execution and transfer execution to different parts of the exec_com segment. Currently there are twelve control statements:

&label and &goto

&attach, &detach, and &input_line

&command_line, &ready, and &print

&quit

&if, &then, &else

As the list indicates, ampersands signify the start of a control statement. Normally, control statements must start at the beginning of a line without any leading blanks. However, a &then can be on the same line as an &if, and other control statements can follow either &then or &else on the same line. For instance:

&if. . .

&then &goto...

or

&if... &then &goto...

Some control statements set conditions for the ensuing input or execution of commands while others alter the normal sequence of command execution. An instance of the former is the &print statement. The execution of this statement causes the input which follows it to be printed at your terminal.

To illustrate this type of control let's look at the execution of another exec_com segment, called query.ec:

tmpD9-3.gif

When you invoke the exec_com command on this segment:

! exec_com query.ec

you will get the following output:

tmpD9-4.gif

You will notice that, in addition to the things this segment is designed to print, all of the segment's command lines are reprinted in the output. This can be prevented by another statement that establishes the conditions for the execution of subsequent commands, the &command_line off control statement. As a matter of fact, this control is almost always used in exec_com segments because the command lines seldom need to be reprinted. If we were to place &command_line off at the beginning of query.ec, invocation would produce:

tmpD9-5.gif

The &quit control statement is another of those that set conditions in that it marks the end of the exec_com segment. It is good practice to include the &quit statement because later you may want to place several exec_coms together in one exec_com segment. In those cases it will be necessary to mark clearly where one exec_com ends and another begins.

Then there are those control statements that alter the normal sequence of execution, the most obvious of which is the &if statement. This is used primarily with the &then and &else statements, and by using other control statements with these, you can further enhance the versatility you have to deal with varying situations. For instance, by including a &goto statement with a &then statement, you can skip over commands and go to a specific location when conditions specified by &if exist.

To understand this type of control statement, let's look at an illustration which uses it. The following exec_com segment is more intricate than our earlier examples because it combines command lines, a variety of control statements, and active functions, and it requires argument substitution.

tmpD9-6.gif

After turning off printing of its command lines, this exec_com tests two segments for likeness with the compare command used as an active function. The two segments to be compared are supplied as arguments in the exec_com command line. The compare active function returns the word "true" if the contents of both segments are the same and the word "false" if the contents are different. The control statement &if operates on the word that is returned. When the word "true" is returned, the &if statement shifts control to the &then control statement. When the word "false" is returned, the &if statement shifts control to the &else control statement. (The &if control statement is similar to the if command in that a then statement is required but an else statement is not.)

The clause following &then, which must be on the same line, can include a command line, an optional argument, and the null statement. It can also include other control statements, except &label, &if, &then, and &else. These conditions are the same for the clause following &else.

Because the only action desired when the compare active function returns true is that one of the segments be printed, the clause following &then is simply the print command and a pathname argument. The &else condition, on the other hand, requires a further switching of control because it involves more than one command or control statement. Thus you use a &goto statement with a name, in this case "process," which automatically switches the point of execution to the &label statement with the matching name. Execution then resumes at the line immediately following &label.

Notice here that the line following &else is &quit. This statement causes the current invocation of exec_com, that is, all the subsequent command lines, to cease, which is exactly what you want when the condition is true and the &then statement has been executed. If &quit were not included, execution would go to the second &if statement even when the original condition of the compare active function proved true.

The second &if control statement in this sample exec_com is designed to compare the segment supplied as the second optional argument with a third segment. If the compare active function returns "true" here, the &then clause, using the print command with iteration, has the first two segments printed at your terminal. When the comparison of the second and third segments returns "false," control shifts instead to the &else control statement, which has all three segments printed.

start_up.ec

The start_up.ec is a special exec_com segment that contains commands to be executed each time you log in, before anything is read from your terminal. In fact, you do not even need to invoke the exec_com command for this segment; it is automatically invoked as part of the login procedure. The only things necessary for this automatic invocation are that the segment be named "start_up.ec" and that it reside in your home directory.

This feature of the exec_com is useful because users usually have certain operations that they want performed almost every time they log in. With a start_up.ec they are saved the work of typing the required commands each time they enter the system. And if ever they wish to log in without executing these commands, they simply add the control argument -no_start_up (-ns) to login.

There are several commands that almost all users include in their start_ups. These include:

abbrev

so that you can use your personal abbreviations during each terminal session

print_motd

so that the system prints the message of the day when you haven't seen it before

print_mail

so the system automatically prints your mail

accept_messages

so you receive messages from other users online

Then, of course, you probably would want to include the &command_line off control statement at the beginning of your start_up so that the segment's commands aren't printed at your terminal each time.

There are also quite a few other commands that it is useful to invoke when you start up, and we will discuss some of the most important ones. To take advantage of your terminal's capabilities and make typing easier, you may want to include several set_tty commands in your start_up on a conditional basis. This command provides many options and is invoked through the usage:

set_tty -modes OPTION1,OPTION2,OPTION3...,OPTIONn

Note that with the control argument -modes there is the unusual use of commas between its character strings, but there are no spaces.

Ordinarily, several set_tty commands are used conditionally in the start_up.ec so that you have the proper one actually invoked for the terminal you are using at a particular log in. Thus you would have a set of &if &then control statements for each type of terminal you might log in from. An example of the form is:

&if [equal [user term type] TN300]

&then set_tty -modes 11118 ,crecho,lfecho

The user term_type active function would return your particular terminal type and if it proved, by the active function equal, to be the TermiNet 300, then the important modes would be set appropriately.

In the -modes control argument above, the 11118 sets the line length at the TN300 to 118 columns or spaces. Without this specification your terminal would be set at 79 columns, the default setting. You could also use a number other than 118, depending on the limitations of a particular terminal. The crecho (carriage return echo) designation creates a situation in which a carriage return is provided each time a linefeed is typed. The lfecho (linefeed echo) designation provides for one linefeed each time you hit the carriage return key. Thus you can get a newline by typing either a carriage return or a linefeed. You must note, however, that the TermiNet 300 has an automatic linefeed switch which, when turned on, provides a linefeed automatically each time a carriage return is typed. So if you have that switch on and have the lfecho mode set, you will get a double linefeed.

In order to gain an in-depth understanding of how start_up.ecs work and what they are used for, let's look at a somewhat complicated but quite realistic example of one. For the sake of explaining this example, the lines are numbered, though of course they couldn't be in the actual exec_com.

tmpD9-7.gif

This start_up.ec handles three conditions: logging in as an interactive user, which is what you ordinarily do, running an absentee job (discussed in Section 7) and creating a new process once you're already logged in.

Line 2 checks to see if you are logging in as an interactive user, and if you are, sends control to line 5. The &2 argument is supplied automatically by the Multics system. When the start_up.ec is invoked, the system places either the word "interactive" or the word "absentee" in the second optional argument position so one of those words is supplied in the &2 location; and here it is compared by the equal active function to the character string "interactive." If the active function returns false, because the invocation is for an absentee process, then execution begins at line 3, which sends a message to your mailbox telling you what date and time your absentee job began running.

Line 4 then takes control and sends execution to the &label statement at line 19. The word "all" is an appropriate &label name here because the lines following 19 are always executed when the start_up.ec is invoked, whether it be for interactive, absentee, or new process use. Those lines invoke the abbrev command and mark the end of the exec_com segment.

If the check for interactive usage in line 2 had proved true, then you would be going through a different execution sequence before getting to lines 19 through 21. In such a case, control would, of course, skip over lines 3 and 4, go to line 5 and start executing at line 6.

Line 6 checks to see if you are creating a new process at this point in your interactive usage. A new process is created by the new_proc command or by an error that cancels your process. The new_proc command cancels the current process and sets up a new one, using the control arguments given initially with the login command and the optional argument to the new_proc command itself. It's as though you logged out and immediately logged back in. The start_up.ec is again invoked automatically when a new process is started. The optional argument the system automatically gives in the first position with the invocation of the start_up.ec is the character string login or new_proc, depending on whether the invocation is coming from the initial log in or from the new_proc command. So in line 6, &1 is substituted with one of those strings. If that string is new_proc, then the equal active function returns true and execution is shifted to line 10, &label new_proc.

What the &goto control statement in line 6 passes over are executions that would have been accomplished at the initial interactive log in and would not need repeating. Line 7 provides for a special handling of the message of the day. If you have no start_up, the message is printed each time you log in; but when you once place a start_up.ec in your home directory, the system assumes that you are taking action on your own to examine the message and thus stops printing it automatically. When incorporated in your start_up, the print_motd command keeps a copy of the last message of the day in a segment (called Person_id.motd) in your home directory. Each time the command is invoked, usually during execution of your start_up, it compares the current message with the saved one and prints the current one if it is changed from the saved copy. This way you don't have to see the message again and again when once is enough.

The check_info_segs command in line 8 is handy to have in the start_up because it prints a list of new or modified segments in the info segment library each time you log in. Much like the print_motd command, it controls the listing by saving the current time in the user's profile so that when it is invoked again, it lists only info segments created or modified since the last invocation.

Line 9 checks your mail for you each time you log in interactively. By making the procedure conditional, as is done here, you can avoid the full printing of all your mail that you would get if you simply used the print_mail command. This way, nothing is printed if you have no mail, and only "You have mail." is printed if you do. When this latter is the case, you can then type the read_mail command, which allows you a great deal of control over printing the messages, after the start_up has finished executing.

Provided you are not running an absentee process, your start_up executions will eventually get to line 10, whether from the &goto in line 6 or "by executing through line 9. In either case, you will then pass on to lines 11 through 18 and then, of course, go on from 19 through 21, as in all start_up invocations. What happens here is first, in line 11, an unconditional setting of terminal modes to polite. Polite holds the printing of any output sent to your terminal (e.g., messages from other users) while you are typing input until the carriage returns to the left margin (i.e., when you type a newline).

The accept_messages command in line 12 allows your process to accept messages sent by the send_message command and notices of the form "You have mail." sent by the send_mail command. The -print control argument prints all messages sent to you by the send_message command since the last time you were logged in and accepting messages. Messages and mail notices sent while you are logged in will then be printed out at your terminal, in this case when you next return the carriage to the left margin because you have the polite mode on. This is necessary because the check for mail, performed by line 9 in this start_up, does not check for messages sent by the send_message command.

If, while you are logged in, you defer messages with the defer_messages command, all mail and messages sent to you are saved in your mailbox and can be read with the read_mail or print_messages commands.

The only lines in this start up that we haven't discussed thus far are 13 through 18. These 6 lines contain three tests of terminal types, the procedure explained above using TN300 as an example. The three included in this start_up are three that a user is very likely to encounter - TN300, ASCII, and VIP7801. But this start_up.ec would not prevent its user from logging in on another terminal. That terminal's default modes would simply be in force because no special modes are set by the start_up. Of course, the user could easily set modes for that terminal by using the set_tty command while logged in.

The only convention used in these six lines that was not explained earlier is the ^lfecho mode. The circumflex character (^) acts as a negation, turning the particular mode off. This start_up uses ^lfecho because the TermiNet 300 has the automatic linefeed switch.

Because it provides a way of storing oft-used command sequences, an abbreviated way of invoking them, and an internal means for controlling their execution, the exec_com command is one of the most powerful and useful features of the Multics system. And there are yet other aspects of the feature which can enhance your efficiency on the system. There are facilities for adding search paths to the exec_com search list, for answering questions generated by exec_com sequences, for combining a number of exec_coms into one segment, and for handling conditions raised during execution of an exec_com. In fact, there are ways that you can call one exec_com from another, or reenter the current one at an earlier point. These additional features are explained in full in the MPM Commands.

 

<< Previous Section                                          Next Section >>

Contents | 1 | 2 | 3 | 4 | 5 | 6 | 7 | A | B | C