TCL - How to print on the screen th messages that where printed during execution of exec command?

10,039

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.

Share:
10,039
Narek
Author by

Narek

Game developer.

Updated on June 04, 2022

Comments

  • Narek
    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
    Narek about 13 years
    So there is no way to get it runtime?
  • Donal Fellows
    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
    Donal Fellows about 13 years
    If you're not collecting the output, directly connecting the subprocess to stdout is better.