                     #tocTable of Contents  
#toc0Name 
bgexec - Run programs in the background while
handling Tk events. 
#toc1Synopsis 
blt::bgexec varName ?option value?... program ?arg?...
#toc2Description 
The 
bgexec command executes programs in the background, allowing
Tk to handle events.  A global Tcl variable 
varName is set when the program
has completed. 
#toc3Introduction 
Tcl's 
exec command is very useful for gathering
information from the operating system.  It runs a program and returns the
output as its  result.  This works well for Tcl-only applications. But for
Tk applications, a problem occurs when the program takes time to process.
 Let's say we want the get the disk usage of a directory.  We'll use the Unix
program 
du to get the summary. set out [exec du -s $dir]puts "Disk usage for $dir is $out"
While du is running, scrollbars won't respond.  None of the Tk widgets will
be redrawn properly.  The 
send command won't work. And the worst part is that
the application appears hung up or dead. The problem is that while 
execis waiting for 
du to finish, Tk is not able to handle X events. The 
bgexeccommand performs the same functions as 
exec, but also allows Tk to handle
events.  You can execute a long-running program and the Tk widgets will behave
normally.  When the program finishes, its output and the exit status are
written to Tcl variables.  This makes it easy to monitor and save the output
of a program. 
#toc4Example 
Here is the disk usage example again, this time using
bgexec. The syntax to invoke "du" is exactly the same as the previous example,
when we used 
exec. global myStatus myOutputblt::bgexec myStatus -output myOutput du -s $dir
puts "Disk usage for $dir is $myOutput"
Two global variables, myStatus and myOutput, will be set by bgexec when
du has completed. MyStatus will contain the program's exit status.  MyOutput,
specified by the 
-output option, will store the output of the program. You
can also terminate the program by setting the variable 
myStatus.  If myStatusis set before 
du has completed, the process is killed. Under Unix, this
is done sending by a configurable signal (by default it's SIGKILL). Under
Win32, this is done by calling 
TerminateProcess. It makes no difference
what 
myStatus is set to. set myStatus {}There are several bgexec options to collect different types of information.
global myStatus myOutput myErrsblt::bgexec myStatus -output myOutput -error myErrs du -s $dir
The -error option is similar to -output.  It sets a global variable when the
program completes.  The variable will contain any data written to stderr
by the program. 
The 
-output and -error variables are set only after the program
completes.  But if the program takes a long time, to run you may want to
receive its partial output.  You can gather data as it becomes available
using the 
-onoutput option.  It specifies a Tcl command prefix.  Whenever
new data is available, this command is executed, with the data appended
as an argument to the command. 
proc GetInfo { data } {    puts $data
}
blt::bgexec myStatus -onoutput GetInfo du -s $dir
When output is available, the procedure GetInfo is called. The -onerror option
performs a similar function for the stderr data stream. 
Like 
exec, bgexecreturns an error if the exit code of the program is not zero.  If you think
you may get a non-zero exit code, you might want to invoke 
bgexec from within
a 
catch. catch { blt::bgexec myStatus -output myOutput du -s $dir }By default, bgexec will wait for the program to finish. But you can detach
the program making ampersand (&) the last argument on the command line. 
global myStatus myOutputblt::bgexec myStatus -output myOutput du -s $dir &
Bgexec will return immediately and its result will be a list of the spawned
process ids.  If at some point you need to wait for the program to finish
up, you can use 
tkwait.  When the program finishes, the variable myStatuswill be written to, breaking out the 
tkwait command. global myStatus myOutputblt::bgexec myStatus -output myOutput du -s $dir &
    ...tkwait variable myStatus
#toc5Syntax 
The 
bgexec command takes the following form:     blt::bgexec varName?
option value?... program ?arg?... VarName is the name of a global variable which
is set when  
program has finished executing.  The exit status of will be
stored in 
varName.  The exit status is a list of a status token, the process-id
of the program, the exit code, and a status message.  You can also prematurely
terminate the program by setting 
varName.  Under Unix, the program will
be sent a signal to terminate it (by default the signal is a SIGKILL; see
the 
-killsignal option). Program is the name of the program to be executed
and 
args are any extra arguments for program.  The syntax of program and
args is the same as the exec command. So you can redirect I/O, execute pipelines,
etc. (see the 
exec manual for further information) just like exec.  If the
last argument is an ampersand (&), the program will be run detached, and
bgexec will return immediately.  VarName will still be set with the return
status when 
program completes. 
#toc6Options 
Option refers to the switch name always
beginning with a dash (-). 
Value is the value of the option.  Option-value
pairs are terminated either by the program name, or double dashes (--). The
following options are available for 
bgexec: 
-decodeerror encodingName  Specifies the encoding of the stderr channel. This affects only data returned
to the Tcl interpreter.  No translation  is done on file redirection. 
For example if data is to be converted from Unicode for use in Tcl, you
would use the "unicode" encoding. The default is that no  tranlation is
performed. 
-decodeoutput encodingName  Specifies the encoding of the stdout channels. This affects only data returned
to the Tcl interpreter.  No translation  is done on file redirection. 
For example if data is to be converted from Unicode for use in Tcl, you
would use the "unicode" encoding. The default is that no  tranlation is
performed. 
-error varName  Specifies that a global variable 
varName is to be set with the contents
of stderr after the program has completed.  
-keepnewline boolean Specifies
that a trailing newline should be retained in the  output. If 
boolean is
true, the trailing newline is truncated from the output of the 
-onoutputand 
-output variables.   The default value is true. -killsignal signal Specifies
the signal to be sent to the program when  terminating. This is available
only under Unix.  
Signal can either be a number (typically 1-32) or a mnemonic
(such as SIGINT). If 
signal is the empty string,  then no signal is sent.
 The default signal is 
9 (SIGKILL). -lasterror varName Specifies a variable
varName that is updated whenever data becomes available from standard error
of the program. 
VarName is a global variable. Unlike the -error option, data
is available as soon as it arrives. 
-lastoutput varName  Specifies a variable
varName that is updated whenever data becomes available from standard output
of the program. 
VarName is a global variable. Unlike the -output option, data
is available as soon as it arrives. 
-linebuffered boolean Specifies that
updates should be made on a line-by-line basis. Normally when new data is
available 
bgexec will set the variable (-lastoutput and -lasterror options)
or invoke the command (
-onoutput and -onerror options) delivering all the
new data currently available.  If 
boolean is true, only one line at a time
will be delivered.  This can be useful when you want to process the output
on a line-by-line basis.   The default value is 
false. -output varName Specifies that a global variable 
varName is to be set with the output of
the program, once it has completed.  If this option  is not set, no output
will be accumulated. 
-onerror command Specifies the start of a Tcl command
that will be executed whenever new data is available from standard error.
The data is appended to the command as an extra argument before it is executed.
-onoutput command  Specifies the start of a Tcl command that will be executed
whenever new data is available from standard output. The data is appended
to the command as an extra argument before it is executed. 
-update varName 
Deprecated. This option is replaced by -lasterror. -- This marks the end of
the options.  The following argument will be considered the name of a program
even if it starts with  a dash (
-). #toc7Preemption 
Because 
bgexec allows Tk to
handle events while a program is running, it's possible for an application
to preempt itself with further user-interactions.  Let's say your application
has a button that runs the disk usage example.  And while the 
du program
is running, the user accidently presses the button again.  A second 
bgexecprogram will preempt the first.  What this means is that the first program
can not finish until the second program has completed. 
Care must be taken
to prevent an application from preempting itself by blocking further user-interactions
(such as button clicks).  The BLT 
busy command is very useful for just these
situations. See the 
busy manual for details. 
#toc8Differences with Fileevent 
Since
Tk 4.0, a subset of 
bgexec can be also achieved using the fileevent command.
 The steps for running a program in the background are: 
Execute the program
with the 
open command (using the "|" syntax) and save the file handle. global fileId set fileId [open "|du -s $dir" r]
Next register a Tcl code snippet with fileevent to be run whenever output
is available on the file handle.  The code snippet will read from the file
handle and save the output in a variable. 
fileevent fileId readable {     if { [gets $fileId line] < 0 } {
    close $fileId    set output $temp    unset fileId temp    } else {
    append temp $line    }
}
The biggest advantage of bgexec is that, unlike fileevent, it requires
no additional Tcl code to run a program.  It's simpler and less error prone.
 You don't have to worry about non-blocking I/O. It's handled tranparently
for you. 
Bgexec runs programs that fileevent can not. Fileevent assumes that
the when stdout is closed the program has completed.  But some programs,
like the Unix 
compress program, reopen stdout, fooling fileevent into thinking
the program has terminated.  In the example above, we assume that the program
will write and flush its output line-by-line.  However running another program,
your application may block in the 
gets command reading a partial line. Bgexeclets you get back the exit status of the program. It also allows you to
collect data from both stdout and stderr simultaneously. Finally, since
data collection is handled in C code, 
bgexec is faster. You get back to
the Tk event loop more quickly, making your application seem more responsive.
#toc9See Also 
busy, exec, tkwait 
#toc10Keywords 
exec, background, busy 
Table of Contents #sect0Name #sect1Synopsis #sect2Description #sect3Introduction #sect4Example #sect5Syntax #sect6Options #sect7Preemption #sect8Differences with Fileevent #sect9See Also #sect10Keywords 