Running other programs from Tcl - exec, open

So far the lessons have dealt with programming within the Tcl interpreter. However, Tcl is also useful as a scripting language to tie other packages or programs together. To accomplish this function, Tcl has two ways to start another program:

The open call is the same call that is used to open a file. If the first character in the file name argument is a "pipe" symbol (|), then open will treat the rest of the argument as a program name, and will run that program with the standard input or output connected to a file descriptor. This "pipe" connection can be used to read the output from that other program or to write fresh input data to it or both.

If the "pipe" is opened for both reading and writing you must be aware that the pipes are buffered. The output from a puts command will be saved in an I/O buffer until the buffer is full, or until you execute a flush command to force it to be transmitted to the other program. The output of this other program will not be available to a read or gets until its output buffer is filled up or flushed explicitly.

(Note: as this is internal to this other program, there is no way that your Tcl script can influence that. The other program simply must cooperate. Well, that is not entirely true: the expect extension actually works around this limitation by exploiting deep system features.)

The exec call is similar to invoking a program (or a set of programs piped together) from the prompt in an interactive shell or a DOS-box or in a UNIX/Linux shell script. It supports several styles of output redirection, or it can return the output of the other program(s) as the return value of the exec call.

open |progName ?access?
Returns a file descriptor for the pipe. The progName argument must start with the pipe symbol. If progName is enclosed in quotes or braces, it can include arguments to the subprocess.
exec ?switches? arg1 ?arg2? ... ?argN?
exec treats its arguments as the names and arguments for a set of programs to run. If the first args start with a "-", then they are treated as switches to the exec command, instead of being invoked as subprocesses or subprocess options.

switches are:

-keepnewline
Retains a trailing newline in the pipeline's output. Normally a trailing newline will be deleted.
--
Marks the end of the switches. The next string will be treated as arg1, even if it starts with a "-"

arg1 ... argN can be one of: There are many I/O redirection commands. The main subset of these commands is:
|
Pipes the standard output of the command preceding the pipe symbol into the standard input of the command following the pipe symbol.
< fileName
The first program in the pipe will read input from fileName.
<@ fileID
The first program in the pipe will read input from the Tcl descriptor fileID. fileID is the value returned from an open ... "r" command.
<< value
The first program in the pipe will read value as its input.
> fileName
The output of the last program in the pipe will be sent to fileName. Any previous contents of fileName will be lost.
>> fileName
The output of the last program in the pipe will be appended to fileName.
2> fileName
The standard error from all the programs in the pipe will be sent to fileName. Any previous contents of fileName will be lost.
2>> fileName
The standard error from all the programs in the pipe will be appended to fileName.
>@ fileID
The output from the last program in the pipe will be written to fileID. fileID is the value returned from an open ... "w" command.

If you are familiar with shell programming, there are a few differences to be aware of when you are writing Tcl scripts that use the exec and open calls.