Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why do I get this error when closing a pipe

26 views
Skip to first unread message

Cecil Westerhof

unread,
Dec 4, 2017, 5:44:06 PM12/4/17
to
I open a read-only pipe with:
set vmstat [open "|vmstat -n 60"]

I close it immediately with:
close ${vmstat}

This takes almost a minute and ends in the following error:
child killed: write on pipe with no readers
while evaluating {close ${vmstat}}

What is happening here.

This is on Debian 9.

--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

Rich

unread,
Dec 4, 2017, 6:13:16 PM12/4/17
to
Cecil Westerhof <Ce...@decebal.nl> wrote:
> I open a read-only pipe with:
> set vmstat [open "|vmstat -n 60"]
>
> I close it immediately with:
> close ${vmstat}
>
> This takes almost a minute and ends in the following error:
> child killed: write on pipe with no readers
> while evaluating {close ${vmstat}}
>
> What is happening here.

You are opening a pipe to vmstat, the immediately closing the Tcl end.

Vmstat is still running, and tries to write to its end of the pipe.

The error message you get is likely from vmstat, not Tcl.

Read the data vmstat writes first, then close the pipe.

Cecil Westerhof

unread,
Dec 4, 2017, 7:28:06 PM12/4/17
to
Even when reading all the output that can be delivered, I get this
error. The problem is that vmstat never stops. In the place I use it,
that is no problem, because I do not want it to stop.
But what to do if the situation changes and I do want to stop a
program that runs forever?

Rich

unread,
Dec 4, 2017, 9:16:56 PM12/4/17
to
You have a couple choices there.

One would be to redirect stderr of the command, and wrap your close in
a catch:

set vmstat [open "|vmstat -n 60 2> /dev/null"]
...
catch {close $vmstat}

However, the redirect above is Unix specific (might work on MacOS,
likely won't work properly on windows).


Your other option is to (assuming you have Tcl 8.6) use the chan
command to create a pipe, then use exec and output redirection to send
vmstat's output into the writer side of the pipe and read the reader
side in Tcl. In this case exec will return the process id of the
vmstat. You'd save that somewhere and use it to kill the process later
(which would mean either installin Tclx, or exec'ing a "kill" (which
would be Unix specific again).

Presuming you are ok with Unix specifics (all your items seem to be for
managing Unix/Linux systems so far) then the redirect in the open plus
the "catch" method is by far simpler.

Robert Heller

unread,
Dec 4, 2017, 9:29:29 PM12/4/17
to
When you close the pipe, you kill the process doing the writing. You should
be able to use "catch" to catch the error:

set vmstat [open "|vmstat -60" r]
# read from vmstat for a while...
# done with vmstat, make it go away:
if {[catch {close $vmstat} message]} {
if {[regexp {^child killed: write on pipe with no readers} $message] < 0} {
# Some real live error
error $message
}
}
# vmstat is gone.

>

--
Robert Heller -- 978-544-6933
Deepwoods Software -- Custom Software Services
http://www.deepsoft.com/ -- Linux Administration Services
hel...@deepsoft.com -- Webhosting Services

0 new messages