Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 599
Narek Avatar asked May 11 '11 05:05

Narek


People also ask

Which Tcl command uses to print message?

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.

What is exec command in Tcl?

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.

What does puts do in Tcl?

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.

Is Echo a Tcl command?

This command is part of the TclX package.


2 Answers

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]
like image 83
Hai Vu Avatar answered Sep 27 '22 21:09

Hai Vu


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.

like image 44
kostix Avatar answered Sep 27 '22 23:09

kostix