How to Issue Commands

Rexx makes it easy to issue commands. The basic rule is that whatever Rexx cannot process directly gets passed to the current command environment. You can:

Rexx processes your program one clause at a time. It examines each clause to determine if it is:

If the clause is none of the above, Rexx evaluates the entire clause as an expression and passes the resulting string to the current command environment.

If the string is a valid command for that environment, the command handler will process it as if you had entered it at the command prompt.

The following example shows a Rexx clause that uses the Windows DIR command to display a list of files in the current directory.

/* display current directory */
say "DIR command using Rexx"
dir

The clause dir is not a Rexx instruction or a label, so Rexx evaluates it and passes the resulting string to the operating system that recognizes the string DIR as one of its commands and processes it.

Letting Rexx evaluate the command as an expression might cause problems, however. Try adding a path to the DIR command in the above program (such as, dir c:\\Windows). The Windows command in this case is an incorrect Rexx expression. The program ends with an error.

A safer way to issue commands is by enclosing the command in quotes, which makes the command a literal string. Rexx does not evaluate the contents of strings, so the string is passed to Windows as-is. Here is an example using the PATH command:

/* display current path */
say "PATH command using Rexx"
"path"

The following example, dp&per;cmd, shows a program using the DIR and PATH commands. The PAUSE command is added to wait for the user to press a key before issuing the next instruction or command. Borders are added too.


DIR and PATH commands
/* dp&per;cmd -- Issue DIR and PATH commands to Windows */
say "="~copies(40) /* display line of equal */
/* signs (=) for a border */
"dir" /* display listing of */
/* the current directory */
"pause" /* pauses processing and */
/* tells user to "Press */
/* any key to continue." */
say "="~copies(40) /* display line of = */
"path" /* display the current */
/* PATH setting */

When you specify the following:

[C:\\]rexx dp

a possible output would be:

========================================
The volume label in drive C is WIN.
Directory of C:\\EXAMPLES
. 10-16-94 12:43p
.. 10-16-94 12:43p
EX4_1 CMD nnnn 10-16-94 1:08p
DEMO TXT 117 10-16-94 1:10p
4 File(s) 12163072 bytes free
Press any key when ready . . .
========================================
PATH=C:\\WINDOWS
[C:\\]
Note

Usually, when executing a host command addressed to the Windows or Unix/Linux command shell, a new process is created in the system command handler to execute the command. Changes in a child process environment do not change the parent process environment. Therefore, any change in the environment, such as a directory change, made by a host command executed in a child process would not be reflected in the process running the Rexx program.

The interpreter attempts to mitigate this to some extent by executing some host commands in the process running the Rexx program, rather than in a child process. This is done so that changes to the environment made by executing the host command are visible in the process running the Rexx program.

This is only done when the host command line is simple. That is, the command line must contain a single command, without redirection and without pipe. On Windows this applies to the CD and SET commands. On Unix-like systems, including Linux, this applies to cd, set, unset and export. Rather than remembering the rules, it may be easier to avoid a potential problem by using the built in directory() or value() functions rather than issuing a host command for cd, set, etc.


Environment commands (Windows)
'cd c:\\tmp' /* executed in Rexx program process */
'cd "c:\\R&D (secret)"' /* executed in Rexx program process */
'cd c:\\windows && dir c:' /* executed in child process (2 commands) */
'd:' /* executed in Rexx program process */
'set myvar=my value' /* executed in Rexx program process */

Environment commands (Unix)
'cd' /* executed in Rexx program process: go to HOME directory */
'cd ~/"R&D (secret)"' /* executed in Rexx program process: go to HOME/R&D (secret) */
'cd ~/"R&D \\"secret\\""' /* executed in Rexx program process: go to HOME/R&D "secret" */
'cd ~john' /* executed in Rexx program process: go to John's home directory */
'cd /tmp && pwd' /* executed in child process (2 commands) */
'set myvar=my value' /* executed in Rexx program process */
'export myvar=my value' /* executed in Rexx program process */
'unset myvar' /* executed in Rexx program process */