В сценарии tcl, как я могу использовать puts для одновременной записи строки в консоль и в файл?

# Prints the string in a file
puts $chan stderr "$timestamp - Running test: $test"

# Prints the string on a console
puts "$timestamp - Running test: $test"

Есть ли способ отправить выходные данные на экран и в файл журнала одновременно? В настоящее время у меня есть две вышеуказанные строки одна за другой в моем сценарии для достижения этой цели.

Или есть другое решение в tcl?


person Nachiketa    schedule 19.09.2016    source источник


Ответы (2)


Используйте следующий процесс вместо puts:

proc multiputs {args} {
    if { [llength $args] == 0 } {
        error "Usage: multiputs ?channel ...? string"
    } elseif { [llength $args] == 1 } {
        set channels stdout
    } else {
        set channels [lrange $args 0 end-1]
    }
    set str [lindex $args end]
    foreach ch $channels {
        puts $ch $str
    }
}

Примеры:

# print on stdout only
multiputs "1"

# print on stderr only
multiputs stderr "2"

set brieflog [open brief.log w]
set fulllog [open detailed.log w]
# print on stdout and in the log files
multiputs stdout $brieflog $fulllog "3"
person Leon    schedule 19.09.2016

Это не то, что я широко использовал, но, похоже, оно работает (только Tcl 8.6+):

Вам нужен пакет преобразования канала tcl::transform::observe:

package require tcl::transform::observe

Откройте файл журнала для записи и установите для буферизации значение none:

set f [open log.txt w]
chan configure $f -buffering none

Зарегистрируйте stdout в качестве получателя:

set c [::tcl::transform::observe $f stdout {}]

Все, что будет записано в канал $c, теперь попадет и в лог-файл, и в stdout.

puts $c foobar

Обратите внимание, что было бы более разумно иметь преобразование канала поверх stdout, с каналом в файл журнала в качестве получателя, но я не смог заставить это работать.

Документация: chan, open, пакет, путы, set, tcl::transform::observe (package)< /а>

person Peter Lewerin    schedule 20.09.2016