TCL - How to print on the screen th messages that where printed during execution of exec command?
Solution 1
Not perfect (as it require writing to external file):
set log [exec executable_file | tee log.txt >@stdout]
The output will be displayed immediately, at the same time, saved to 'log.txt'. If you don't care about saving the output:
set log [exec executable_file >@stdout]
Solution 2
Use open "| ..."
and asyncronous linewise reading from the returned descriptor, like this:
proc ReadLine fd {
if {[gets $fd line] < 0} {
if {[chan eof $fd]} {
chan close $fd
set ::forever now
return
}
}
puts $line
}
set fd [open "| ./executable_file"]
chan configure $fd -blocking no
chan event $fd readable [list ReadLine $fd]
vwait forever
See this wiki page for more involved examples.
In a real program you will probably already have an event loop running so there would be no need for a vwait
specific to reading the output of one command.
Also if you need to collect the output, not just [puts]
each line after it has been read, you will pobably need to create a global (usually namespaced) variable, initialize it to "", pass its name as another argument to the callback procedure (ReadLine
here) and append the line to that variable's value.
Comments
-
Narek about 2 years
Say I have want to execute a script or and executable file by printing runtime the output of execution.
When I do:
set log [exec ./executable_file] puts $log
Then it waits a long time and then prints everything at once. But I want runtime printing. How can I do this?
-
Narek about 13 yearsSo there is no way to get it runtime?
-
Donal Fellows about 13 years+1: Note that running a command in a pipeline can change its buffering behavior; the expect script
unbuffer
can help with that. -
Donal Fellows about 13 yearsIf you're not collecting the output, directly connecting the subprocess to stdout is better.