[sbron]: In unix/linux there is a standard command named https://man7.org/linux/man-pages/man1/tee.1.html%|%''tee''%|%, that duplicates its input to both standard output and a file. Inspired on that concept, I came up with some code to add similar functionality to Tcl. The module adds a ''tee'' command to Tcl. It has three subcommands: '''tee replace''' ''chan'' ''file'': Copy all data sent to ''chan'' to ''file''. ''chan'' must have been opened for writing. If ''file'' exists, it is truncated. This is the default, so it can also be invoked as: '''tee''' ''chan'' ''file''. '''tee append''' ''chan'' ''file'': Copy all data sent to ''chan'' to ''file''. ''chan'' must have been opened for writing. If ''file'' exists, the data is appended. '''tee channel''' ''chan'' ''fd'': Copy all data sent to ''chan'' to an already open ''fd''. Both ''chan'' and ''fd'' must have been opened for writing. To stop copying the data to file and return ''chan'' to normal, use: '''chan pop''' ''chan''. Usage example: ====== package require tee tee stdout /tmp/sessionlog.txt puts "Hello, World!" ====== Place the following code in a file called ''tee-1.0.tm'' and place it somewhere in the tcl::tm path: ====== namespace eval tee { variable methods {initialize finalize write} namespace ensemble create -subcommands {replace append channel} \ -unknown [namespace current]::default namespace ensemble create -command transchan -parameters fd \ -subcommands $methods } proc tee::default {command subcommand args} { return [list $command replace $subcommand] } proc tee::channel {chan fd} { chan push $chan [list [namespace which transchan] $fd] } proc tee::replace {chan file} { chan push $chan [list [namespace which transchan] [open $file w]] } proc tee::append {chan file} { chan push $chan [list [namespace which transchan] [open $file a]] } proc tee::initialize {fd handle mode} { variable methods return $methods } proc tee::finalize {fd handle} { close $fd } proc tee::write {fd handle buffer} { puts -nonewline $fd $buffer return $buffer } ======