Write to stdout, but save tail -n 1 to a file

429 views Asked by At

Is there anyway to run a process in the background while showing the real time updates in the stdout and only saving the last line (tail -n 1 savefile) to a file? There can be anywhere between 1 and 15 tests running at the same time and I need to be able to see that the tests are running but I do not want to save the entire text output.

I should mention since the tests are running in the background I am using a checkpid loop to wait for the tests to finish

also if it helps this is how my script is running the tests...

set runtest [exec -ignorestderr bsub -I -q lin_i make $testvar SEED=1 VPDDUMP=on |tail -n 1 >> $path0/runtestfile &]

I have found that if I use | tee it causes the checkpid loop to skip but if I do |tee it does not display output.

1

There are 1 answers

1
Donal Fellows On

It's going to be better to use a simpler pipeline with explicit management of the output handling in Tcl, instead of using tail -n (and tee) to simulate it.

set pipeline($testvar) [open |[list bsub -I -q lin_i make $testvar SEED=1 VPDDUMP=on]]
fileevent $pipeline($testvar) readable [list handleInput $testvar]
fconfigure $pipeline($testvar) -blocking 0

# The callback for when something is available to be read
proc handleInput {testvar} {
    upvar ::pipeline($testvar) chan ::status($testvar) status
    if {[gets $chan line] >= 0} {
        # OK, we've got an update to the current status; stash in a variable
        set status $line
        # Echo to stdout
        puts $line
        return
    } elseif {[eof $chan]} {
        if {[catch {close $line}]} {
            puts "Error from pipeline for '$testvar'"
        }
        unset chan
        # I don't know if you want to do anything else on termination
        return
    }
    # Nothing to do otherwise; don't need to care about very long lines here
}

This code, plus a little vwait to enable event-based processing (assuming you're not also using Tk), will let you read from the pipeline while not preventing you from doing other things. You can even fire off multiple pipelines at once; Tcl will cope just fine. What's more, setting a write trace on the ::status array will let you monitor for changes across all of the pipelines at once.