How to fork an external program and get back it's stdout and stderr without blocking and WITH a timeout! proc _exec { prog var { tmpfile "" } { i 0 } { to 5 } } { if { ! [ regexp {^file\d+$} $prog ] } { set tmpfile _exec-[ clock seconds ][ clock clicks ] set tmpfile /tmp/$tmpfile if { [ catch { set fid [ open "|$prog 2>$tmpfile" ] fconfigure $fid -blocking off fconfigure $fid -buffering full } err ] } { file delete -force $tmpfile return -code error "_exec: $err" } } else { set fid $prog } set ret [ read $fid ] if { ($i / 10) >= $to } { if { ! [ string length $ret ] } { set ret timed_out } } if { [ string length $ret ] || [ file size $tmpfile ] } { set pids [ pid $fid ] catch { ::close $fid } foreach pid $pids { catch { exec kill -KILL $pid } } set fid [ open $tmpfile r ] set err [ read $fid [ file size $tmpfile ] ] catch { ::close $fid } file delete -force $tmpfile set ::$var [ list $ret $err ] } else { incr i after 100 [ list _exec $fid $var $tmpfile $i ] } } Usage example: # of course, you really want to trace the variable, # not vwait on it! _exec "curl http://www.ligo.caltech.edu" foo vwait ::foo puts $::foo