Differences from other command interpreters

The following sections outline some of the deliberate differences in design between the 32-bit Command Interpreter and the 16-bit CMD supplied with IBM OS/2.

Differences in configuration

The 32-bit Command Interpreter is configured by specifying options in its command tail when it is invoked. The CMD_xxxx_INIT environment variables can be used to set options that will be inherited by child command interpreters. Setting these variables in the CONFIG.SYS file will affect (unless overridden) all command interpreter processes on the system.

Differences in the parser

The command interpreter adheres strictly to the syntax given in the IBM OS/2 documentation when parsing command lines.

The original COMMAND, supplied with PC/MS-DOS, had some very unusual ideas about parsing command lines. Several characters, including equals ('='), comma (','), plus ('+'), and full stop ('.') were treated like white space. The treatment of the equals sign, for example, seems to have been in order that commands entered at the command prompt could resemble directives in the CONFIG.SYS file.

These ideas failed to take off in the middle 1980s, however. Developers and users voted with their feet and stuck with the command line paradigms of the UNIX shells, where only whitespace counted as a separator. Almost no third-party DOS programs support their use. They haven't been mentioned in the official MS/PC-DOS documentation since at least the days of version 3.0. They have never been mentioned in the OS/2 documentation for the command interpreter at all.

The 32-bit Command Interpreter was designed from the ground up so that its operation, including the way that it parsed command lines, was straightforward, simple to understand, and compatible with what the IBM OS/2 documentation actually says. It does not support the undocumented and deprecated vestiges of the parser of the MS/PC-DOS version 2.x COMMAND command interpreter.

Various side-effects of the original parser in COMMAND have passed into user folklore. Here are some common mistakes that people assume will work, despite the fact that the IBM OS/2 documentation describes no such thing, what they will do, and how to achieve what is actually desired:

Differences in what commands are built-in

A command is only built-in to the command interpreter itself if it absolutely has to be.

The original COMMAND, supplied with PC/MS-DOS, was designed to run in an environment where DOS was booted from a 360KiB floppy disc. Commands such as DIR and COPY were built in to it firstly in order to save disc space, because having them as separate executables would waste space by unnecessarily duplicating common code, and secondly because it also allowed the convenience of the DOS boot volume being replaced with a "work" volume without having to replace the original DOS disc in order to run such common commands. Even though even DOS quickly outgrew this environment, the design was never changed, and was eventually inherited by the 16-bit CMD supplied with IBM OS/2.

The 32-bit Command Interpreter finally revises this design decision. Only those commands that actually must be built-in commands (because, for example, they need to modify the state of the command interpreter process itself and so cannot run in a separate child process) are built-in commands. All other commands, even commands that are built-in commands in the 16-bit CMD supplied with IBM OS/2, are external commands.

This approach has the advantage that it allows commands to be replaced, if needed, by workalikes with extended or modified functionality, without replacing or modifying the command interpreter itself. To replace "DIR" with an alternative directory listing program of one's choice, for example, one simply renames or replaces "DIR.EXE".

The problem with wasting disc space by duplicating common code is neatly overcome by using the ability of 32-bit OS/2 programs to use dynamic link libraries, which DOS does not have. This significantly reduces the size of external commands such as CLS.EXE, DELAY.EXE, and MKDIR.EXE for example, the bulk of whose contents would (if they were DOS programs) be common library code. Since the DLL used by these commands is already in memory where IBM OS/2 can quickly locate it, because it is also used by the command interpreter itself, there is less code that IBM OS/2 has to load into memory from disc for each of these external commands.

Differences in environment variable handling

Environment variable names are case-sensitive

32-bit OS/2 actually allows environment variable names to contain both uppercase and lowercase letters. The 16-bit CMD supplied with IBM OS/2 hides this handy feature, by changing all environment variable names to uppercase.

The 32-bit Command Interpreter does not convert the case of environment variable names. An environment variable named "path" is distinct from one named "PATH" (and from one named "Path", for that matter).

Note: The "well-known" environment variables all have all-uppercase names.

Having more than 64KiB of environment variables is supported.

In the 16-bit CMD supplied with IBM OS/2, because it is a 16-bit program, there is a limit of 64KiB to the total combined size of its environment. The 32-bit Command Interpreter is a 32-bit program and has no such limit. The limit is the amount of available free memory in the command interpreter process.

However, assigning more than 64KiB of environment variables and then running a 16-bit OS/2 program will confuse that program, and may cause it to crash in unexpected ways. Some versions of IBM OS/2 will also refuse to run any programs at all. If you use more than 64KiB of environment variables, only run Pure 32-bit programs.

Differences in date and time

The DATE and TIME external commands and the various implicit variables in the 32-bit Command Interpreter all support multiple user-configurable timezones. They require the IBM OS/2 system real-time clock to be set correctly.

Switching timezones is simply a matter of altering the TZ environment variable using the SET command. The new timezone takes effect immediately in the current command interpreter process, and will be reflected in the prompt if the $D and $T sequences happen to have been used. It will also affect any child processes that the command interpreter process then creates, such as if the DATE or TIME external commands are run, since they will inherit the new TZ environment variable from the command interpreter.

For example, the command

[c:\]set TZ=EST5EDT

switches the command interpreter's timezone to U.S. Eastern Time, whereas the command

[c:\]set TZ=EST-10EDT,M10.5.0,M3.5.0

switches the command interpreter's timezone to Australian Eastern Time.

Differences in how wildcards that match directory names are handled

External commands do not treat source or destination name arguments differently depending from whether or not they happen to match the name of an existing directory.

The COPY, DEL, DIR, and RENAME commands built into the 16-bit CMD supplied with IBM OS/2 check each source name argument to see whether it matches the name of an existing directory. If it does, then the commands implicitly append "\*" to the argument. The COPY command also checks the destination name to see whether it matches the name of an existing directory and, similarly, implicitly appends "\*" to it if it does.

In both cases, this results in behaviour that is dependent from what directories exist at the time the command is run, and that is thus surprising. Without context, one cannot say exactly what a command will do.

The external COPY, DEL, DIR, MORESTD, MOVE, RENAME, and TYPE commands supplied with the 32-bit Command Interpreter treat all source name arguments in a uniform manner, irrespective of whether or not they happen to match existing directory names. Similarly, the COPY, MOVE, and RENAME commands also treat the destination name argument in a uniform manner, irrespective of whether or not it happens to match an existing directory name.

Ironically, the MOVE command built into the 16-bit CMD supplied with IBM OS/2 handles source name arguments in this manner, too.

The quirks of the 16-bit CMD supplied with IBM OS/2 with respect to source names can be duplicated by using the /OLDSRCDIR standard option. The quirks with respect to the destination name can be duplicated by using the /OLDDESTDIR standard option.

To make this behaviour the default, place these options in the initialisation environment variables for each command:

SET CMD_COPY_INIT=/OLDSRCDIR+ /OLDDESTDIR+
SET CMD_DEL_INIT=/OLDSRCDIR+
SET CMD_DIR_INIT=/OLDSRCDIR+
SET CMD_MORESTD_INIT=/OLDSRCDIR+
SET CMD_MOVE_INIT=/OLDSRCDIR+ /OLDDESTDIR+
SET CMD_RENAME_INIT=/OLDSRCDIR+ /OLDDESTDIR+
SET CMD_TYPE_INIT=/OLDSRCDIR+

Differences in how command script files are handled

The 32-bit Command Interpreter keeps command script files open, for read access (and with the "deny none" sharing mode), whilst they are being interpreted.

The 16-bit CMD supplied with IBM OS/2 processes command script files a line at a time, opening, reading, and closing the script file afresh for each individual line of the script.

The 32-bit Command Interpreter keeps command script files open for the entire duration that they are being executed. This is more efficient, as it allows read-ahead of the command script file to be buffered in memory, and eliminates the overhead of repeatedly searching directories to open the file. (The increased overhead is especially noticable for command scripts located on slow floppy disc drives or on remote drives to which network access is slow.) It is also more robust, since it obviates the need for a SYS1816 error (which the 16-bit CMD supplied with IBM OS/2 displays whenever it comes to open a command script partway through interpreting it, in order to read in the next line, and finds that the file has gone missing in the meantime).

Because the command script file is held open as it is interpreted, its name cannot be modified. So it cannot be deleted or renamed. It is IBM OS/2 itself that enforces this prohibition.

Note: Some text editors "overwrite" a file with new content by actually renaming it to a "backup" name and then writing a wholly new file with the original name. Such text editors will not be capable of modifying a command script file as it is executing because of the restriction imposed by IBM OS/2 on renaming open files.

Differences in file "modes"

There are no file "modes" fabricated by the commands in the 32-bit Command Interpreter. There are no distinctions between "text" and "binary" files.

The standard /A option in the various 32-bit Command Interpreter commands can be used without a colon, and does not have quirky alternative meanings.

The idea that there are such things as "text" and "binary" files originates in DOS programs. It is part of a shared delusion created by many DOS programs, whose run-time libraries fabricate this distinction.

For example, The "traditional" COPY command has the CP/M semantics of behaving differently when copying in "binary mode" to when copying in "text mode". It has the /A and /B options to specify which mode to use. This is all implemented by the command itself, as can even be seen by looking at the source code from the FreeDOS COPY command. This causes a conflict in JP Software's 4OS2, where /A is a standard option that means "select files by attribute". JP Software's 4OS2 consequently requires an explicit colon when /A: is used with the COPY command with the latter meaning, to distinguish it from the former meaning.

In fact, DOS itself never made any such distinction between "text" and "binary" files at all. IBM OS/2 makes no such distinction, either. To both operating systems, files are just sequences of octets, which can have any value, and none of which have special semantics.

The commands in the 32-bit Command Interpreter use these actual, native, OS/2 semantics. Files are just files. There are no magical "end of file characters" that will cause the TYPE command to prematurely stop writing a file's contents. The COPYSTD and COPYPLUS commands have no "binary" and "text" modes. Files are copied octet-for-octet, exactly as they stand. The copy commands have no need for an alternative meaning for the /A option and they do not need to mimic the syntactic inconsistency of JP Software's 4OS2. There are no special quirky meanings for the /A option to the copy commands, depending from whether it contains a colon or not.


The 32-bit Command Interpreter is © Copyright Jonathan de Boyne Pollard. "Moral" rights are asserted.