RUNCOM
RUNCOM was a groundbreaking command script interpreter developed by French engineer Louis Pouzin in 1963–1964 for the Compatible Time-Sharing System (CTSS), an early operating system at MIT's Computation Center.[1] It allowed users to create files containing sequences of CTSS commands with parameter substitution, enabling the automation of repetitive tasks such as file renaming, moving, updating, compiling, and system maintenance.[1] Pouzin coined the term "shell" to describe RUNCOM, likening it to a lightweight interface that encapsulated and executed command scripts much like subroutine libraries in programming.[1] Developed amid the rapid evolution of time-sharing systems in the early 1960s, RUNCOM addressed the limitations of manual command entry on CTSS, which ran on a modified IBM 7094 computer and supported multiple users interactively.[2] By permitting overnight execution of scripts, it boosted productivity for system administrators and programmers handling large directories of files, quickly becoming a popular tool within the MIT community.[1] Pouzin's innovation stemmed from his frustration with writing dozens of individual commands, prompting him to envision commands as modular building blocks.[1] RUNCOM's design directly influenced subsequent command interpreters, serving as the conceptual precursor to the shell in the Multics operating system, which Pouzin helped develop starting in 1965.[2] This Multics shell, in turn, inspired the Unix shell created by Ken Thompson and others in the early 1970s, establishing the shell as a core component of Unix-like systems.[2] Today, the term "shell" remains the standard for command-line interfaces in operating systems worldwide, underscoring RUNCOM's enduring legacy in computing history.[3]History
Origins in CTSS
The Compatible Time-Sharing System (CTSS), developed at MIT in the late 1950s and early 1960s, represented a pioneering effort in multi-user operating systems, enabling interactive computing on an IBM 7094 mainframe through innovations like disk-based file storage and remote terminal access.[2] As one of the first systems to support multiple simultaneous users, CTSS highlighted limitations in command execution, particularly for repetitive tasks that required manual intervention in a shared environment.[2] To address these challenges, Louis Pouzin, a member of MIT's computer center staff, created RUNCOM circa 1963 as a macro command processor integrated into CTSS.[1] Pouzin designed RUNCOM specifically to automate sequences of commands, serving as an early tool for scripting in a time-sharing system that lacked native built-in scripting capabilities.[1] This innovation allowed users to streamline workflows, such as file management or program compilation, by substituting arguments into predefined command sets, thereby reducing the tedium of interactive repetition.[1] RUNCOM was implemented in the MAD (Michigan Algorithm Decoder) language, which allowed for faster and more maintainable code.[1] In its initial form, RUNCOM operated by processing command macros stored in disk files rather than supporting real-time interactive behavior, enabling users to submit scripts for sequential execution.[2] This file-based approach facilitated overnight batch processing, permitting users to initiate long-running tasks and depart, which significantly enhanced productivity in CTSS's resource-constrained setting.[1] Pouzin later described it as a "sort of shell driving the execution of command scripts, with argument substitution," underscoring its foundational role in command automation.[1]Development and Enhancements
RUNCOM was initially implemented in CTSS in 1963–1964 as a basic macro processor for command substitution and automation.[1] By 1965, as Multics development began, Pouzin shifted focus to designing an advanced shell for the new system, building on RUNCOM's concepts.[1] His April 1965 papers, including "The SHELL: A Global Tool for Calling and Chaining Procedures in the System" and "RUNCOM - A Macro-Procedure Processor for the 636 System," outlined these proposals for the GE-636 system in early Multics design.[4][5] Within CTSS, RUNCOM saw limited further development, as Pouzin departed MIT in mid-1965.[1]Design and Functionality
Core Architecture
RUNCOM functioned as a command script interpreter within the Compatible Time-Sharing System (CTSS), designed to automate sequences of commands by processing predefined scripts rather than providing an interactive command-line interface like modern shells.[6] Unlike contemporary shells that interpret user input in real time and maintain an execution environment, RUNCOM read scripts sequentially from disk and submitted expanded command lists directly to the CTSS supervisor for processing, emphasizing batch automation over interactive dialogue.[6] This design, developed by Louis Pouzin in 1963-1964, treated scripts as sequences of CTSS commands to streamline repetitive tasks in the time-sharing environment.[1] At its core, RUNCOM read input sequentially from disk files with secondary names such as RUNCOM or BCD, which contained sequences of CTSS commands stored line by line, often with placeholders for parameters.[6] These files, located in user or system directories, were accessed using CTSS file input routines like RDLINA or supervisor buffers, processing each logical BCD record as a distinct request.[6] Upon invocation via a command like RUNCOM followed by the filename, the processor expanded the script by substituting formal arguments (e.g., dummy symbols in CHAIN commands) with actual values provided at runtime.[6] Parameter substitution formed the central mechanism, enabling parameterized scripts by replacing placeholders with user-supplied values prior to execution.[6] The expanded output was then directed to the SCHAIN library subroutine, which managed command chaining by storing the list in a stack and interfacing with the CTSS command processor for sequential execution.[6] This integration relied on supervisor calls, such as TSX RUNCOM, to transfer control, ensuring the processed commands were treated as standard CTSS requests without RUNCOM maintaining its own interpretive loop.[6] RUNCOM operated primarily in batch mode, executing scripts autonomously once initiated, but supported limited interactivity through commands like QUES for conditional prompts during processing.[6] It processed commands as if entered directly at the console but handled interruptions via mechanisms like SAVFIL and RERUN, preserving core images in temporary SAVED files for resumption.[6] This batch-oriented approach, with optional interactive elements, aligned with CTSS's emphasis on efficient resource sharing, delegating all execution to the system's command executor rather than embedding environmental state management within RUNCOM itself.[6]Script Processing Mechanisms
RUNCOM processes scripts by reading commands sequentially from disk files with secondary names such as RUNCOM or BCD, executing them as a chain of CTSS commands. Each line in the file represents a single command, with arguments separated by spaces; blank lines are ignored during processing. The system initiates execution via a RUNCOM command followed by optional arguments, terminating upon reaching the end of the file or an explicit (END) marker.[6] The parameter substitution process involves replacing placeholders, or dummy symbols, with actual values provided at invocation, prior to submitting the expanded commands to the CTSS supervisor for execution. This substitution occurs within CHAIN pseudo-commands, enabling parameterized scripts; for instance, a command such as CHAIN FILE (NIL) (END) ED FILE MAD would replace dummy arguments in the file's commands with user-supplied values. The expanded script is then processed line by line, preserving the core image and machine state through temporary SAVED files to ensure continuity across compatible commands.[6] Support for comments allows users to include non-executable lines in scripts, with lines beginning with *** fully ignored during processing and those starting with treated as comments that are printed to the console but not executed. This mechanism facilitates [documentation](/page/Documentation) and [debugging](/page/Debugging) without altering script flow; for example, a line might output a descriptive message like "START 'X' FOR BOOK [FAP](/page/FAP)" during runtime.[6] Control structures in RUNCOM provide basic flow management, enabling conditional execution through commands like QUES, which checks conditions such as file existence and branches accordingly—for instance, prompting "FILE ALPHA BETA NOT FOUND" if absent. Nesting and recursion of RUNCOM calls within chains support more complex sequences, though explicit looping is not natively implemented and relies on repeated chaining. These features allow for rudimentary decision-making and iterative-like behavior in automated tasks.[6] Processed commands are routed through the CHAIN mechanism for interpretation by the CTSS command supervisor, directing output to the user's console in standard format, such as "W t" for wait states or "R t1 + t2" for ready messages. Additional output from utilities like RUNPRT displays substituted parameters in lines limited to 14 words, while status queries from QUES print interactive prompts like "DO YOU WISH TO PROCEED?" Upon completion, control returns to the caller, potentially leaving a final SAVED file representing the dormant system state.[6]Usage
Basic Syntax and Commands
RUNCOM scripts in the Compatible Time-Sharing System (CTSS) are executed using theRUNCOM command followed by the script's filename, such as RUNCOM SCRIPT, which triggers the sequential processing of commands stored in the file as if entered interactively at the console.[6]
Scripts are saved as disk files with a user-defined primary name and a secondary name of RUNCOM, BCD, or SAVED to enable recognition by the RUNCOM processor; for instance, a file named SCRIPT RUNCOM or X BCD follows CTSS's two-word naming convention, where names are right-adjusted and blank-padded.[6] These files must be in BCD (Binary Coded Decimal) format, either line-marked or line-numbered, to ensure proper reading and execution.[6]
The basic structure of a RUNCOM script consists of a simple text file containing one CTSS command per line, executed in sequence without branching unless specified by core commands; blank lines are ignored during processing.[6] Comments are supported using $ to denote lines that print during execution or *** for lines that are entirely skipped, facilitating documentation within the script.[6] Simple macros can be incorporated via standard CTSS commands like CHAIN for basic symbol definition, though advanced substitution is handled separately.[6]
A minimal RUNCOM script without parameters might automate a compilation sequence, as in the following example saved as SCRIPT RUNCOM:
Invoking this withEDL FILE1 MAD MAD FILE1 LOADGO FILE1EDL FILE1 MAD MAD FILE1 LOADGO FILE1
RUNCOM SCRIPT would edit, assemble, and load-execute the file FILE1 in MAD language, streamlining repetitive development steps.[6]
Parameter Handling and Chaining
RUNCOM supported parameter substitution to enable dynamic scripting, allowing users to pass arguments at invocation that were replaced by placeholders within the script. Positional parameters were denoted by$1, $2, and so on, corresponding to the first, second, and subsequent arguments provided when executing a RUNCOM file, such as RUNCOM scriptname arg1 arg2. These substitutions facilitated customization of CTSS commands by incorporating user-supplied inputs directly into command lines, with excess blanks removed and a single space inserted between parameters for clean execution. Arguments longer than six characters were truncated from the left, limiting their utility in contexts requiring full identifiers.[6]
The CHAIN command extended this capability by linking multiple scripts or transferring control to another file, enabling sequential execution of command sequences for complex workflows. In a RUNCOM file, CHAIN could specify up to five commands per line, with dummy symbols like ALPH or BET serving as placeholders for arguments that were substituted at runtime. For instance, a script might include CHAIN ALPHA MAD RESUME, where ALPH and MAD were replaced by provided arguments. This mechanism preserved the core image between compatible commands (e.g., those using LOAD-SAVE pairs), allowing chains to maintain system state across invocations. Additionally, the SCHAIN subroutine call, like A = SCHAIN. (FILNAM, ARG1, ARG2), executed chains with parameter substitution in a programmatic context.[6][1]
Examples of parameterized scripts illustrate practical applications in CTSS environments. A simple script file named GREET BCD containing ECHO Hello $1 would output "Hello USER" when invoked as RUNCOM GREET USER, substituting the user's name into the ECHO command for personalized feedback. For more involved tasks, a script could chain file operations: CHAIN SPLIT FIL1 N1 COMBIN FIL1 N2, run as RUNCOM process datafile 100 200, where $1 (datafile) is split at line 100 ($2) and recombined up to line 200 ($3), automating data processing without manual intervention each time. Such substitutions integrated seamlessly with CTSS utilities like EDIT or LOAD, enhancing script reusability for repetitive maintenance.[6]
Despite these features, RUNCOM's parameter handling had notable limitations, lacking full variable scoping and supporting only basic branching rather than complex conditionals. Parameters were strictly positional with no mechanism for named variables or reassignment, restricting scripts to linear or simply nested flows without advanced logic like multi-way decisions. Command buffers were capped at 20 words, chains at five commands per line, and temporary SAVED files generated during execution (e.g., ...00n [SAVED](/page/Saved!)) risked loss without explicit preservation via SAVFIL, further constraining long-running or deeply nested operations. Special arguments like (NIL) for ignoring inputs or (END) for termination provided minimal flexibility but did not overcome the absence of robust control structures.[6]