diff options
Diffstat (limited to 'doc/exec.n')
-rw-r--r-- | doc/exec.n | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/doc/exec.n b/doc/exec.n new file mode 100644 index 0000000..70ace32 --- /dev/null +++ b/doc/exec.n @@ -0,0 +1,452 @@ +'\" +'\" Copyright (c) 1993 The Regents of the University of California. +'\" Copyright (c) 1994-1996 Sun Microsystems, Inc. +'\" Copyright (c) 2006 Donal K. Fellows. +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH exec n 8.5 Tcl "Tcl Built-In Commands" +.so man.macros +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +exec \- Invoke subprocesses +.SH SYNOPSIS +\fBexec \fR?\fIswitches\fR? \fIarg \fR?\fIarg ...\fR? ?\fB&\fR? +.BE +.SH DESCRIPTION +.PP +This command treats its arguments as the specification +of one or more subprocesses to execute. +The arguments take the form of a standard shell pipeline +where each \fIarg\fR becomes one word of a command, and +each distinct command becomes a subprocess. +.PP +If the initial arguments to \fBexec\fR start with \fB\-\fR then +they are treated as command-line switches and are not part +of the pipeline specification. The following switches are +currently supported: +.TP 13 +\fB\-ignorestderr\fR +. +Stops the \fBexec\fR command from treating the output of messages to the +pipeline's standard error channel as an error case. +.TP 13 +\fB\-keepnewline\fR +. +Retains a trailing newline in the pipeline's output. +Normally a trailing newline will be deleted. +.TP 13 +\fB\-\|\-\fR +. +Marks the end of switches. The argument following this one will +be treated as the first \fIarg\fR even if it starts with a \fB\-\fR. +.PP +If an \fIarg\fR (or pair of \fIarg\fRs) has one of the forms +described below then it is used by \fBexec\fR to control the +flow of input and output among the subprocess(es). +Such arguments will not be passed to the subprocess(es). In forms +such as +.QW "\fB<\fR \fIfileName\fR" , +\fIfileName\fR may either be in a separate argument from +.QW \fB<\fR +or in the same argument with no intervening space (i.e. +.QW \fB<\fIfileName\fR ). +.TP 15 +\fB|\fR +. +Separates distinct commands in the pipeline. The standard output +of the preceding command will be piped into the standard input +of the next command. +.TP 15 +\fB|&\fR +. +Separates distinct commands in the pipeline. Both standard output +and standard error of the preceding command will be piped into +the standard input of the next command. +This form of redirection overrides forms such as 2> and >&. +.TP 15 +\fB<\0\fIfileName\fR +. +The file named by \fIfileName\fR is opened and used as the standard +input for the first command in the pipeline. +.TP 15 +\fB<@\0\fIfileId\fR +. +\fIFileId\fR must be the identifier for an open file, such as the return +value from a previous call to \fBopen\fR. +It is used as the standard input for the first command in the pipeline. +\fIFileId\fR must have been opened for reading. +.TP 15 +\fB<<\0\fIvalue\fR +. +\fIValue\fR is passed to the first command as its standard input. +.TP 15 +\fB>\0\fIfileName\fR +. +Standard output from the last command is redirected to the file named +\fIfileName\fR, overwriting its previous contents. +.TP 15 +\fB2>\0\fIfileName\fR +. +Standard error from all commands in the pipeline is redirected to the +file named \fIfileName\fR, overwriting its previous contents. +.TP 15 +\fB>&\0\fIfileName\fR +. +Both standard output from the last command and standard error from all +commands are redirected to the file named \fIfileName\fR, overwriting +its previous contents. +.TP 15 +\fB>>\0\fIfileName\fR +. +Standard output from the last command is +redirected to the file named \fIfileName\fR, appending to it rather +than overwriting it. +.TP 15 +\fB2>>\0\fIfileName\fR +. +Standard error from all commands in the pipeline is +redirected to the file named \fIfileName\fR, appending to it rather +than overwriting it. +.TP 15 +\fB>>&\0\fIfileName\fR +. +Both standard output from the last command and standard error from +all commands are redirected to the file named \fIfileName\fR, +appending to it rather than overwriting it. +.TP 15 +\fB>@\0\fIfileId\fR +. +\fIFileId\fR must be the identifier for an open file, such as the return +value from a previous call to \fBopen\fR. +Standard output from the last command is redirected to \fIfileId\fR's +file, which must have been opened for writing. +.TP 15 +\fB2>@\0\fIfileId\fR +. +\fIFileId\fR must be the identifier for an open file, such as the return +value from a previous call to \fBopen\fR. +Standard error from all commands in the pipeline is +redirected to \fIfileId\fR's file. +The file must have been opened for writing. +.TP 15 +\fB2>@1\0\fR +. +Standard error from all commands in the pipeline is redirected to the +command result. This operator is only valid at the end of the command +pipeline. +.TP 15 +\fB>&@\0\fIfileId\fR +. +\fIFileId\fR must be the identifier for an open file, such as the return +value from a previous call to \fBopen\fR. +Both standard output from the last command and standard error from +all commands are redirected to \fIfileId\fR's file. +The file must have been opened for writing. +.PP +If standard output has not been redirected then the \fBexec\fR +command returns the standard output from the last command +in the pipeline, unless +.QW 2>@1 +was specified, in which case standard error is included as well. +If any of the commands in the pipeline exit abnormally or +are killed or suspended, then \fBexec\fR will return an error +and the error message will include the pipeline's output followed by +error messages describing the abnormal terminations; the +\fB\-errorcode\fR return option will contain additional information +about the last abnormal termination encountered. +If any of the commands writes to its standard error file and that +standard error is not redirected +and \fB\-ignorestderr\fR is not specified, +then \fBexec\fR will return an error; the error message +will include the pipeline's standard output, followed by messages +about abnormal terminations (if any), followed by the standard error +output. +.PP +If the last character of the result or error message +is a newline then that character is normally deleted +from the result or error message. +This is consistent with other Tcl return values, which do not +normally end with newlines. +However, if \fB\-keepnewline\fR is specified then the trailing +newline is retained. +.PP +If standard input is not redirected with +.QW < , +.QW << +or +.QW <@ +then the standard input for the first command in the +pipeline is taken from the application's current standard input. +.PP +If the last \fIarg\fR is +.QW & +then the pipeline will be executed in background. +In this case the \fBexec\fR command will return a list whose +elements are the process identifiers for all of the subprocesses +in the pipeline. +The standard output from the last command in the pipeline will +go to the application's standard output if it has not been +redirected, and error output from all of +the commands in the pipeline will go to the application's +standard error file unless redirected. +.PP +The first word in each command is taken as the command name; +tilde-substitution is performed on it, and if the result contains +no slashes then the directories +in the PATH environment variable are searched for +an executable by the given name. +If the name contains a slash then it must refer to an executable +reachable from the current directory. +No +.QW glob +expansion or other shell-like substitutions +are performed on the arguments to commands. +.SH "PORTABILITY ISSUES" +.TP +\fBWindows\fR (all versions) +. +Reading from or writing to a socket, using the +.QW \fB@\0\fIfileId\fR +notation, does not work. When reading from a socket, a 16-bit DOS +application will hang and a 32-bit application will return immediately with +end-of-file. When either type of application writes to a socket, the +information is instead sent to the console, if one is present, or is +discarded. +.RS +.PP +The Tk console text widget does not provide real standard IO capabilities. +Under Tk, when redirecting from standard input, all applications will see an +immediate end-of-file; information redirected to standard output or standard +error will be discarded. +.PP +Either forward or backward slashes are accepted as path separators for +arguments to Tcl commands. When executing an application, the path name +specified for the application may also contain forward or backward slashes +as path separators. Bear in mind, however, that most Windows applications +accept arguments with forward slashes only as option delimiters and +backslashes only in paths. Any arguments to an application that specify a +path name with forward slashes will not automatically be converted to use +the backslash character. If an argument contains forward slashes as the +path separator, it may or may not be recognized as a path name, depending on +the program. +.PP +Additionally, when calling a 16-bit DOS or Windows 3.X application, all path +names must use the short, cryptic, path format (e.g., using +.QW applba~1.def +instead of +.QW applbakery.default ), +which can be obtained with the +.QW "\fBfile attributes\fI fileName \fB\-shortname\fR" +command. +.PP +Two or more forward or backward slashes in a row in a path refer to a +network path. For example, a simple concatenation of the root directory +\fBc:/\fR with a subdirectory \fB/windows/system\fR will yield +\fBc://windows/system\fR (two slashes together), which refers to the mount +point called \fBsystem\fR on the machine called \fBwindows\fR (and the +\fBc:/\fR is ignored), and is not equivalent to \fBc:/windows/system\fR, +which describes a directory on the current computer. The \fBfile join\fR +command should be used to concatenate path components. +.PP +Note that there are two general types of Win32 console applications: +.RS +.IP [1] +CLI \(em CommandLine Interface, simple stdio exchange. \fBnetstat.exe\fR for +example. +.IP [2] +TUI \(em Textmode User Interface, any application that accesses the console +API for doing such things as cursor movement, setting text color, detecting +key presses and mouse movement, etc. An example would be \fBtelnet.exe\fR +from Windows 2000. These types of applications are not common in a windows +environment, but do exist. +.RE +.PP +\fBexec\fR will not work well with TUI applications when a console is not +present, as is done when launching applications under wish. It is desirable +to have console applications hidden and detached. This is a designed-in +limitation as \fBexec\fR wants to communicate over pipes. The Expect +extension addresses this issue when communicating with a TUI application. +.PP +When attempting to execute an application, \fBexec\fR first searches for +the name as it was specified. Then, in order, +\fB.com\fR, \fB.exe\fR, \fB.bat\fR and \fB.cmd\fR +are appended to the end of the specified name and it searches +for the longer name. If a directory name was not specified as part of the +application name, the following directories are automatically searched in +order when attempting to locate the application: +.IP \(bu 3 +The directory from which the Tcl executable was loaded. +.IP \(bu 3 +The current directory. +.IP \(bu 3 +The Windows NT 32-bit system directory. +.IP \(bu 3 +The Windows NT 16-bit system directory. +.IP \(bu 3 +The Windows NT home directory. +.IP \(bu 3 +The directories listed in the path. +.PP +In order to execute shell built-in commands like \fBdir\fR and \fBcopy\fR, +the caller must prepend the desired command with +.QW "\fBcmd.exe /c\0\fR" +because built-in commands are not implemented using executables. +.RE +.TP +\fBUnix\fR (including Mac OS X) +. +The \fBexec\fR command is fully functional and works as described. +.SH "UNIX EXAMPLES" +.PP +Here are some examples of the use of the \fBexec\fR command on Unix. +To execute a simple program and get its result: +.PP +.CS +\fBexec\fR uname -a +.CE +.SS "WORKING WITH NON-ZERO RESULTS" +.PP +To execute a program that can return a non-zero result, you should +wrap the call to \fBexec\fR in \fBcatch\fR and check the contents +of the \fB\-errorcode\fR return option if you have an error: +.PP +.CS +set status 0 +if {[catch {\fBexec\fR grep foo bar.txt} results options]} { + set details [dict get $options -errorcode] + if {[lindex $details 0] eq "CHILDSTATUS"} { + set status [lindex $details 2] + } else { + # Some other error; regenerate it to let caller handle + return -options $options -level 0 $results + } +} +.CE +.VS 8.6 +.PP +This is more easily written using the \fBtry\fR command, as that makes +it simpler to trap specific types of errors. This is +done using code like this: +.PP +.CS +try { + set results [\fBexec\fR grep foo bar.txt] + set status 0 +} trap CHILDSTATUS {results options} { + set status [lindex [dict get $options -errorcode] 2] +} +.CE +.VE 8.6 +.SS "WORKING WITH QUOTED ARGUMENTS" +.PP +When translating a command from a Unix shell invocation, care should +be taken over the fact that single quote characters have no special +significance to Tcl. Thus: +.PP +.CS +awk '{sum += $1} END {print sum}' numbers.list +.CE +.PP +would be translated into something like: +.PP +.CS +\fBexec\fR awk {{sum += $1} END {print sum}} numbers.list +.CE +.SS "WORKING WITH GLOBBING" +.PP +If you are converting invocations involving shell globbing, you should +remember that Tcl does not handle globbing or expand things into +multiple arguments by default. Instead you should write things like +this: +.PP +.CS +\fBexec\fR ls -l {*}[glob *.tcl] +.CE +.SS "WORKING WITH USER-SUPPLIED SHELL SCRIPT FRAGMENTS" +.PP +One useful technique can be to expose to users of a script the ability +to specify a fragment of shell script to execute that will have some +data passed in on standard input that was produced by the Tcl program. +This is a common technique for using the \fIlpr\fR program for +printing. By far the simplest way of doing this is to pass the user's +script to the user's shell for processing, as this avoids a lot of +complexity with parsing other languages. +.PP +.CS +set lprScript [\fIget from user...\fR] +set postscriptData [\fIgenerate somehow...\fR] + +\fBexec\fR $env(SHELL) -c $lprScript << $postscriptData +.CE +.SH "WINDOWS EXAMPLES" +.PP +Here are some examples of the use of the \fBexec\fR command on Windows. +To start an instance of \fInotepad\fR editing a file without waiting +for the user to finish editing the file: +.PP +.CS +\fBexec\fR notepad myfile.txt & +.CE +.PP +To print a text file using \fInotepad\fR: +.PP +.CS +\fBexec\fR notepad /p myfile.txt +.CE +.SS "WORKING WITH CONSOLE PROGRAMS" +.PP +If a program calls other programs, such as is common with compilers, +then you may need to resort to batch files to hide the console windows +that sometimes pop up: +.PP +.CS +\fBexec\fR cmp.bat somefile.c -o somefile +.CE +.PP +With the file \fIcmp.bat\fR looking something like: +.PP +.CS +@gcc %1 %2 %3 %4 %5 %6 %7 %8 %9 +.CE +.SS "WORKING WITH COMMAND BUILT-INS" +.PP +Sometimes you need to be careful, as different programs may have the +same name and be in the path. It can then happen that typing a command +at the DOS prompt finds \fIa different program\fR than the same +command run via \fBexec\fR. This is because of the (documented) +differences in behaviour between \fBexec\fR and DOS batch files. +.PP +When in doubt, use the command \fBauto_execok\fR: it will return the +complete path to the program as seen by the \fBexec\fR command. This +applies especially when you want to run +.QW internal +commands like +\fIdir\fR from a Tcl script (if you just want to list filenames, use +the \fBglob\fR command.) To do that, use this: +.PP +.CS +\fBexec\fR {*}[auto_execok dir] *.tcl +.CE +.SS "WORKING WITH NATIVE FILENAMES" +.PP +Many programs on Windows require filename arguments to be passed in with +backslashes as pathname separators. This is done with the help of the +\fBfile nativename\fR command. For example, to make a directory (on NTFS) +encrypted so that only the current user can access it requires use of +the \fICIPHER\fR command, like this: +.PP +.CS +set secureDir "~/Desktop/Secure Directory" +file mkdir $secureDir +\fBexec\fR CIPHER /e /s:[file nativename $secureDir] +.CE +.SH "SEE ALSO" +error(n), file(n), open(n) +.SH KEYWORDS +execute, pipeline, redirection, subprocess +'\" Local Variables: +'\" mode: nroff +'\" End: |