I have a tcl script that I pipe through head beacause I am only
interested in the start lines. But this gives:
error writing "stdout": broken pipe
So clearly tclsh does not like it when not all output is consumed.
Can I doe something about it, or should I use try?
Cecil Westerhof <Cecil@decebal.nl> wrote:
I have a tcl script that I pipe through head beacause I am only
interested in the start lines. But this gives:
error writing "stdout": broken pipe
So clearly tclsh does not like it when not all output is consumed.
No, the C stdlib does not like it when a pipe closes before all output
is consumed. TCL's just the messenger here.
Can I doe something about it, or should I use try?
Pipe less data? :)
Otherwise, since head is expected to exit and close the pipe, just
catch the error and ignore it (possibly checking that you got the
expected error and not some other, such as "executable does not
exist").
But you have also not explained why you are piping to head (here, yet
you complained about exec'ing grep for your proc file parser, both
result in the same fork/exec cost).
That is a very standard thing to do in Unix/Linux: when you are only interested in the first part of output. Never had any problem with
that.
* Cecil Westerhof <Cecil@decebal.nl>
| I can now give a value for the number of lines, but when someone uses
| it in a pipe it should not create an error.
Then you absolutely need to 'catch' the puts and handle errors according
to ::errorCode as Rich suggested upthread.
% set fd [open "|echo foo" w]
% fconfigure $fd -buffering none
% catch {puts $fd foo}
1
% set errorCode
POSIX EPIPE {broken pipe}
Am 21.02.22 um 16:35 schrieb Cecil Westerhof:
That is a very standard thing to do in Unix/Linux: when you are only
interested in the first part of output. Never had any problem with
that.
Are you handling a file or piping from a tcl interpreter?
% exec head --lines 1 dummy.txt
###########################################
%
helps: ?? -ignorestderr ??
% set content {=============================================================================
slkdfasdlkfasdlkfsaldkf
asd
fas
fsad
fsad
fsd
f
}
.....
% exec head --lines 1 <<$content ==========================================================================
%
i.e. I can't reproduce your hickup.
Uwe Klein <uwe@klein-habertwedt.de> writes:
Am 21.02.22 um 16:35 schrieb Cecil Westerhof:
That is a very standard thing to do in Unix/Linux: when you are only
interested in the first part of output. Never had any problem with
that.
Are you handling a file or piping from a tcl interpreter?
% exec head --lines 1 dummy.txt
###########################################
%
helps: ?? -ignorestderr ??
% set content
{=============================================================================
slkdfasdlkfasdlkfsaldkf
asd
fas
fsad
fsad
fsd
f
}
.....
% exec head --lines 1 <<$content
========================================================================== >> %
i.e. I can't reproduce your hickup.
I was a bit flabbergasted, because at first I could not reproduce it.
But there has to be enough buffered to get the error.
For example when you have this code in dummy.tcl:
#!/usr/bin/env tclsh
for {set x 0} {$x < 20} {incr x} {
puts "Just some output"
}
and use:
dummy.tcl | head -n 5
everything seems fine.
But when you change the 20 to 21 then sometimes it works and sometimes
it does not.
Up to 35 it is the same.
When making it 50 most of the times (but still not always) you get the
error.
Uwe Klein <uwe@klein-habertwedt.de> writes:
Am 21.02.22 um 16:35 schrieb Cecil Westerhof:
That is a very standard thing to do in Unix/Linux: when you are
only interested in the first part of output. Never had any problem
with that.
Are you handling a file or piping from a tcl interpreter?
% exec head --lines 1 dummy.txt
###########################################
%
helps: ?? -ignorestderr ??
i.e. I can't reproduce your hickup.
I was a bit flabbergasted, because at first I could not reproduce it.
But there has to be enough buffered to get the error.
try {
puts "Just some output"
} on error msg {
if {${::errorCode} == {POSIX EPIPE {broken pipe}}} {
puts stderr "Got a broken pipe."
break
}
puts stderr "Got an unexpected '${::errorCode}'"
exit 1
}
Cecil Westerhof <Cecil@decebal.nl> wrote:
try {
puts "Just some output"
} on error msg {
if {${::errorCode} == {POSIX EPIPE {broken pipe}}} {
puts stderr "Got a broken pipe."
break
}
puts stderr "Got an unexpected '${::errorCode}'"
exit 1
}
Just for your getting to know "try" better, see what its "trap"-handlers
can do for you. :-)
If your tool is *designed* to be used in pipelines that may
shut off before eof, I'd suggest to create an "exit-on-any-error" puts-wrapper, like this:
% proc eoaeputs {args} { if {[catch {puts {*}$args}]} { exit } }
and use that instead of "puts" for all lines written to stdout.
For i/o-tools like that, even a "broken pipe"-message on stderr can
be a nuissance.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 498 |
Nodes: | 16 (2 / 14) |
Uptime: | 42:17:18 |
Calls: | 9,799 |
Calls today: | 1 |
Files: | 13,752 |
Messages: | 6,189,624 |