I know this question has been asked several times here. I have looked at the responses, but couldn't figure out the way it worked.Can you please help me understand.
Here it goes:
I'm trying to source a tcl script on the tclsh command line, and I want to redirect the output of that script into a file.
$ source my_script.tcl
The script my_script.tcl
is something like this:
set output_file final_result
set OUT [open $output_file w]
proc calculate{} {
<commands>
return $result
}
foreach value [calculate] {
puts $output_file "$value"
}
This script still throws out the output onto the stdout, while I expected it to redirect the output into a file specified as "final_result"
Can you please help me understand where I went wrong ?
As you've described here, your program looks OK (apart from minor obvious issues). Your problem is that
calculate
must not write to stdout, but rather needs to return a value. Or list of values in your case, actually (since you're stuffing them throughforeach
).Thus, if you're doing:
Then you're going to get output written stdout and an empty
final_result
(since it's an empty list). If you change that to:then your code will do as expected. That is, from
puts
tolappend result
. This is what I recommend you do.You can capture “stdout” by overriding
puts
. This is a hack!I'm not convinced that the code to detect whether to capture the value is what it ought to be, but it works in informal testing. (It's also possible to capture stdout itself by a few tricks, but the least horrible — a stacked “transformation” that intercepts the channel — takes a lot more code… and the other alternatives are worse in terms of subtleties.)
Assuming that calculate doesn't write to stdout, and all the other good stuff pointed out and suggested by @DonalFellows has been done...
You need to change the puts in the main script to
The script as posted writes to a channel named
final_result
which almost certainly doesn't exist. I'd expect an error from theputs
statement inside theforeach
loop.Don't forget to close the output file - either by exiting from the tclsh interpreter, or preferrably by executing
before you check for anything in it,