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?
The command to output a string in Tcl is the puts command. A single unit of text after the puts command will be printed to the standard output device.
The exec command runs programs from your Tcl script. [*] For example: [*] Unlike other UNIX shell exec commands, the Tcl exec does not replace the current process with the new one.
The puts command is used to write to a file, opened for writing with the open command. We show the contents of the messages file created by the above Tcl script.
This command is part of the TclX package.
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]
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With