N:bgexec

From Linux Man Pages

Jump to: navigation, search
      bgexec - Run programs in the background while handling Tk events.
      


Contents

SYNOPSIS

      blt::bgexec varName ?option value?... program ?arg?...


DESCRIPTION

      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.

INTRODUCTION

      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 applica-
      tions, 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 exec is waiting for du to finish, Tk is not able to handle X
      events.
 
      The bgexec command 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.

EXAMPLE

      Here is the disk usage example again, this time using bgexec.  The syn-
      tax to invoke "du" is exactly the same as the previous example, when we
      used exec.
 
             global myStatus myOutput
             blt::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 myStatus is 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 informa-
      tion.
 
             global myStatus myOutput myErrs
             blt::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  com-
      pletes.   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  avail-
      able  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,  bgexec returns 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  com-
      mand line.
 
             global myStatus myOutput
             blt::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 vari-
      able myStatus will be written to, breaking out the tkwait command.
 
             global myStatus myOutput
             blt::bgexec myStatus -output myOutput du -s $dir &
               ...
             tkwait variable myStatus

SYNTAX

      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 termi-
      nate 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.

OPTIONS

      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 out-
             put.  If boolean is true, the trailing newline is truncated from
             the output of the -onoutput and -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  num-
             ber  (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 avail-
             able 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  avail-
             able 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 when-
             ever  new  data  is  available  from standard error. The data is
             appended to the command as an extra argument before it  is  exe-
             cuted.
 
      -onoutput command
             Specifies the start of a Tcl command that will be executed when-
             ever new data is available from standard  output.  The  data  is
             appended  to  the command as an extra argument before it is exe-
             cuted.
 
      -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 (-).

PREEMPTION

      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 bgexec program will pre-
      empt the first.  What this means is that the first program can not fin-
      ish 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.

DIFFERENCES 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 out-
      put  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  pro-
      grams, 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.
 
      Bgexec lets 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.

SEE ALSO

      busy, exec, tkwait

KEYWORDS

      exec, background, busy

CATEGORY

Personal tools