Last updated:
2001.07.12. child process
Tcl/Tkスクリプトから子プロセスを実行して、 stdoutとstderrを受け取りたい場合。 TclXにはforkがあるようなのですが、Tclにはopenしか無い。 openのpipeを通ってくるのはstdoutだけのようなので、 愚策を労してみました。 …stderrはファイルにリダイレクトして、 tailを子プロセスとして立ち上げ、読み込む。
以下、テスト例です。 tst_child.shというスクリプトを、子プロセスとして、呼び出してみてます。
#!/usr/bin/wish
# test program for child process
# distributable under GPL
# Copyright 2001 zunda <zunda at freeshell.org>
# latest version at http://m-net.arbornet.org/~zunda/ttips.html
# Change Log:
# vre 0.1 Jul 12, 2001 zunda <zunda at freeshell.org>
# Process data from child process
proc GetPipe {fd file} {
# get data from child process
gets $fd data
if [eof $fd] {
# if the child process ended
fileevent $fd readable {}
close $fd
puts "$file Done"
# if temporary file needs to be erased
if {[string length "$file"] > 0} {file delete $file}
# there can be other procedures put here
} else {
# just put the data to the terminal (or do other things)
puts $data
}
}
# example of the foreground job
proc updateClock {} {
.time configure -text [clock format [clock seconds] -format "%D %T"]
after 1000 updateClock
}
# Create child process
# use temporary file to get output from stderr of the child process
set child_stderrfile [exec mktemp ./t.[pid].XXXXXX]
set child_stdout [open "| ./tst_child.sh 2>$child_stderrfile" "r"]
set child_pid [pid $child_stdout]
set child_stderr [open "| tail -q -f --pid=$child_pid $child_stderrfile" "r"]
fileevent $child_stdout readable {GetPipe $child_stdout {}}
fileevent $child_stderr readable {GetPipe $child_stderr $child_stderrfile}
# do foreground process
label .time -text "Clock"
pack .time
button .exit -text "Exit" -command {destroy .}
pack .exit
updateClock
Back to zunda.