ソフト作りのこと

Tcl/Tk programming tips

Last updated:
2001.07.12. child process


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.

[zunda]
zunda <zunda at freeshell.org>