SeinopSys
SeinopSys

Reputation: 8937

TCL script breaks with "child killed: write on pipe with no readers"

After upgrading to Debian Jessie, the tcl motd I set up has been giving me a strange error on login (hostname blanked out):

root     pts/0        XXXX-XX-XX-XXX-X Thu Jun 23 01:49:55 2016 - Thu Jun 23 01:                                                                     50:09 2016  (00:00)
child killed: write on pipe with no readers
    while executing
"exec -- last -F | head -n 2 | tail -n 1 "
    invoked from within
"set lastlog [exec -- last -F | head -n 2 | tail -n 1 ]"
    (file "/etc/motd.tcl" line 24)

I'm puzzled, because running the command myself I get the exact line that's printed on top, but it's not supposed to print anything when ran as part of the script, but rather set it as a value of a variable, as you can see from the referenced line in the error:

set lastlog [exec -- last -F | head -n 2 | tail -n 1 ]

What's happening here that's causing the mysterious error and how can I fix it?

Upvotes: 2

Views: 2810

Answers (2)

Lutz Vieweg
Lutz Vieweg

Reputation: 11

You can use a sub-shell invocation, where the shell does not mind the first command to terminate by signal, as in:

set lastlog [exec -- bash -c "last -F | head -n 2 | tail -n 1"]

This has the advantage of actually terminating the execution of "last" before it emitted its whole output, which is good if that output would be very long.

Upvotes: 1

Donal Fellows
Donal Fellows

Reputation: 137717

The error is caused by one of the subprocesses terminating with a non-zero exit code (which exec is very sensitive to), which in turn is caused by it still having output to produce despite the pipe being closed (a common issue with use of head). The simplest fix for you is to read the whole output of last -F into Tcl and to do the line chopping there. Fortunately, this is easy:

set lastOutputLines [split [exec -- last -F] "\n"]
set lastlog [lindex $lastOutputLines 1]; # Zero-based indexing

As long as the output of last isn't vast, this'll be quick enough.

Upvotes: 3

Related Questions