File: bgexec.man

package info (click to toggle)
tkdesk 2.0-12
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 6,596 kB
  • sloc: tcl: 20,764; ansic: 16,262; sh: 359; makefile: 233
file content (272 lines) | stat: -rw-r--r-- 11,667 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
'\"
'\" Copyright 1991-1997 by Bell Labs Innovations for Lucent Technologies.
'\"
'\" Permission to use, copy, modify, and distribute this software and its
'\" documentation for any purpose and without fee is hereby granted, provided
'\" that the above copyright notice appear in all copies and that both that the
'\" copyright notice and warranty disclaimer appear in supporting documentation,
'\" and that the names of Lucent Technologies any of their entities not be used
'\" in advertising or publicity pertaining to distribution of the software
'\" without specific, written prior permission.
'\"
'\" Lucent Technologies disclaims all warranties with regard to this software,
'\" including all implied warranties of merchantability and fitness.  In no event
'\" shall Lucent Technologies be liable for any special, indirect or
'\" consequential damages or any damages whatsoever resulting from loss of use,
'\" data or profits, whether in an action of contract, negligence or other
'\" tortuous action, arising out of or in connection with the use or performance
'\" of this software.  
'\"
'\" Bgexec command created by George Howlett.
'\"
.so man.macros
.HS bgexec BLT
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
bgexec \- Run Unix commands in the background while handling
Tk events.
.SH SYNOPSIS
\fBbgexec \fIvarName\fR ?\fIoption value\fR?... \fIcommand\fR ?\fIarg\fR?...
.BE
.SH DESCRIPTION
.PP
The \fBbgexec\fR command executes Unix commands in the background,
allowing Tk to handle events.  A global Tcl variable \fIvarName\fR is
set when the command has completed.
.SH INTRODUCTION
Tcl's \fBexec\fR command is very useful for gathering information from
the Unix system.  It runs a Unix command and returns the output of the
command as its result.  This works well for Tcl-only applications. But
in Tk applications, a problem occurs when a Unix command takes time to
process.  For example, let's say we want the get the disk usage of a
directory.  We'll use the Unix command \f(CWdu\fR to get the summary.
.DS
set out [exec du -s $dir]
puts "Disk usage for $dir is $out"
.DE
While \f(CWdu\fR is running, scrollbars won't respond.  None of the Tk
widgets will be redrawn properly.  The \fBsend\fR command won't work.
And the worst part is that the application appears hung up or dead.
The problem is that while the application is waiting for \fIdu\fR
to finish, Tk is not handling X events.
.PP
The \fBbgexec\fR command performs the same functions as \fBexec\fR,
but also allows Tk to handle events.  You can execute a long-running
Unix command and the Tk widgets will behave normally.  When the
command finishes, its output and the exit status are written to Tcl
variables.  This makes it easy to monitor and save the output of a
command.
.SH EXAMPLE
This is the disk usage example again, this time using \fBbgexec\fR.
The Unix command syntax is exactly the same as the previous example,
when we used \fBexec\fR.
.DS
global myStatus myOutput
bgexec myStatus -output myOutput du -s $dir
puts "Disk usage for $dir is $myOutput"
.DE
Two global variables, \f(CWmyStatus\fR and \f(CWmyOutput\fR, will be set by
\fBbgexec\fR when the \f(CWdu\fR command has completed. \f(CWMyStatus\fR
will contain the command's exit status.  \f(CWMyOutput\fR, specified by the
\fB\-output\fR option, will store the output of the command.
.PP
You can also terminate the command by setting the variable \f(CWmyStatus\fR.
If \f(CWmyStatus\fR is set before \f(CWdu\fR has completed, the process
is killed by sending a configurable Unix signal (by default it's
SIGKILL).  It makes no difference what \f(CWmyStatus\fR is set to.
.DS
set myStatus {}
.DE
There are other \fBbgexec\fR options to collect different types of 
information.
.DS
global myStatus myOutput myErrs
bgexec myStatus -output myOutput -error myErrs du -s $dir
.DE
The \fB\-error\fR option is similar to \fB\-output\fR.  It sets a global
variable when the command completes.  The variable will contain
any data written to stderr by the command.
.PP
The \fB\-output\fR and \fB\-error\fR variables are written to only
after the command completes.  If the command takes a long time, you
may want to receive its partial output.  You can gather data as it
becomes available using the \fB\-onoutput\fR 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.
.DS
proc GetInfo { data } {
    puts $data
}
bgexec myStatus -onoutput GetInfo du -s $dir
.DE
When output is available, the procedure \f(CWGetInfo\fR is called.
The \fB\f-onerror\fR option performs a similar function for the stderr
data stream.
.PP
Like \fBexec\fR, \fBbgexec\fR returns an error if the exit code of the
Unix command is not zero.  If you think you may get a non-zero exit
code, you might want to invoke \fBbgexec\fR from within a \fBcatch\fR.
.DS
catch { bgexec myStatus -output myOutput du -s $dir }
.DE
By default, \fBbgexec\fR will wait for the command to finish.
But you can detach the command by adding an ampersand (&) to the
end of the command line.
.DS
global myStatus myOutput
bgexec myStatus -output myOutput du -s $dir &
.DE
\fBBgexec\fR 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
command to finish, you can use \fBtkwait\fR.  When the command
finishes, the variable \f(CWmyStatus\fR will be written to, breaking the
\fBtkwait\fR loop.
.DS
global myStatus myOutput
bgexec myStatus -output myOutput du -s $dir &
	...
tkwait variable myStatus
.DE
.SH SYNTAX
The \fBbgexec\fR command takes the following form:
.sp
\fB	bgexec \fIvarName\fR ?\fIoption value\fR?... \fIcommand\fR ?\fIarg\fR?...
.sp
\fIVarName\fR is the name of a global variable which is set when the
designated Unix command has finished executing.  The exit status of
the command will be stored in \fIvarName\fR.  The exit status is a
list of a status token, the process-id of the command, the exit code,
and a status message.  You can also prematurely terminate the command
by setting \fIvarName\fR.  The command will be sent a signal to
terminate it (by default the signal is a SIGKILL; see the
\fB\-killsignal\fR option).
.PP
\fICommand\fR is the name of the Unix command to be executed and
\fIargs\fR are any extra arguments for \fIcommand\fR.  \fICommand\fR
and \fIargs\fR may be in any form accepted by \fBexec\fR. (See the
\fBexec\fR manual for further information.)  If the last argument is
an ampersand (&), the command will be run detached, and \fBbgexec\fR
will return immediately.  \fIVarName\fR will still be set with the
return status when \fIcommand\fR completes.
.SH OPTIONS
\fIOption\fR is the switch name, always beginning with a dash (\-).
\fIValue\fR is the value of the option.  Option-value pairs are
terminated either by the Unix command name, or double dashes (\-\-).
The following options are available for \fBbgexec\fR:
.TP 
\fB\-error \fIvarName\fR 
.br
Specifies that a global variable \fIvarName\fR is to be set with the
contents of stderr after the command has completed. 
.TP 
\fB\-keepnewline \fIboolean\fR
Specifies that a trailing newline should be retained in the 
output. If \fIboolean\fR is true, the trailing newline is truncated
from the output of the \fB\-onoutput\fR and \fB\-output\fR variables.  
The default value is \f(CWtrue\fR.
.TP 
\fB\-killsignal \fIsignal\fR
Specifies the signal to be sent to the Unix command when 
terminating. \fISignal\fR can either be a number (typically 1-32) or
a mnemonic (e.g. SIGINT). If \fIsignal\fR is the empty string, 
then no signal is sent.  The default signal is \f(CW9\fR (SIGKILL).
.TP 
\fB\-lasterror \fIvarName\fR
Specifies a variable \fIvarName\fR that is updated whenever data
becomes available from standard error of the Unix command.
\fIVarName\fR is a global variable. Unlike the \fB\-error\fR option,
data is available as soon as it arrives.
.TP 
\fB\-lastoutput \fIvarName\fR 
Specifies a variable \fIvarName\fR that is updated whenever data
becomes available from standard output of the Unix command.
\fIVarName\fR is a global variable. Unlike the \fB\-output\fR option,
data is available as soon as it arrives.
.TP 
\fB\-output \fIvarName\fR
.br
Specifies that a global variable \fIvarName\fR is to be set with the
output of the command, after the commmand has completed.  If this option 
is not set, no output will be accumulated.
.TP 
\fB\-onerror \fIcommand\fR
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.
.TP 
\fB\-onoutput \fIcommand\fR 
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.
.TP 
\fB\-update \fIvarName\fR 
Deprecated. This option is replaced by \fB\-onerror\fR.
.TP 
\fB\-\|\-\fR
This marks the end of the options.  The following argument will
be considered the name of a Unix command even if it starts with 
a dash (\fB\-\fR).
.SH PREEMPTION
Because Tk events are handled while a Unix command is running, it's
possible for an application to preempt itself with further
user-interactions.  Let's say your application has a button, that when
pressed runs the disk usage example.  While the \f(CWdu\fR command is
already running, the user may press the button again.  The second
\fBbgexec\fR command will preempt the first.  This means that the
first command can not finish until the second command has completed.
.PP
Care must be taken to prevent an application from preempting itself,
by blocking further user-interactions (such as button clicks).  The
BLT \fBbusy\fR command is very useful in these situations, temporarily
preventing user interaction. See the \fBbusy\fR manual for
details.
.SH DIFFERENCES WITH FILEEVENT
Some of the functionality of \fBbgexec\fR is now be provided in Tk 4.0
with the \fBfileevent\fR command.  The steps for running a command in
the background are:
.PP
Execute the Unix command with the \fBopen\fR command (using the "|"
syntax) and save the file handle.
.DS
global fileId 
set fileId [open "|du -s $dir" r]
.DE
Next register a Tcl code snippet with \fBfileevent\fR 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.
.DS
fileevent fileId readable { 
    if { [gets $fileId line] < 0 } {
	close $fileId
	set output $temp
	unset fileId temp
    } else {
	append temp $line
    }
}
.DE
While this works with the above example, but there are some important
differences.
.PP
The biggest advantage of \fBbgexec\fR is that it requires no
additional Tcl code to run a Unix command.  It's simpler, and
therefore there's less chance of errors being introduced.
.PP
\fBBgexec\fR also handles things that \fBfileevent\fR can not.  For
example, you can't get back the exit status of the command.  In the
code above, we're assuming that the command has completed once stdout
is closed.  The problem is that some commands, like \f(CWcompress\fR,
reopen stdout, which fool \fBfileevent\fR.  We're also assuming that
the Unix command will write its output line-by-line.  Running another
command, your application may block in the \fBgets\fR command, reading
a partial line.  Conversely, \fBbgexec\fR handles non-blocking I/O
tranparently for you.  Finally, since data collection is handled in C
code, \fBbgexec\fR is faster, getting you back to the Tk event loop
more quickly.
.SH SEE ALSO
busy, exec, tkwait
.SH KEYWORDS
exec, background, busy