Re: How to get bash to shut up about SIGPIPE?

From: Paul Jackson <pj@sgi.com>
Date: 2005-04-30 10:22:35
> bash is being an ass about SIGPIPE

You have a multiprocessor, don't you.

The following silly little shell script will provoke the bash SIGPIPE
complaint reliably on a multiprocessor.  It writes a big file, twice,
from a for-loop in a separate bash subshell through a pipe to a command
that exits after seeing one line.

Code Sample 1:

    #!/bin/bash
    for x in 1 2
    do
        cat /etc/termcap	# a big text file
    done | sed 1q

Adding a right trap _inside_ the shell loop that is _before_ the pipe
will reduce the verbosity of the complaint substantially (not show the
line number and text for each command inside the loop that is killed by
the SIGPIPE; rather just show the simple "Broken pipe" error message):

Code Sample 2:

    #!/bin/bash
    for x in 1 2
    do
	trap continue PIPE	# reduce broken pipe screeching
	cat /etc/termcap	# a big text file
    done | sed 1q

Then wrapping the entire pipeline (now that the bogus output is a
constant "Broken pipe" string) in the following manner will filter out
just that noise, leaving whatever else was on stdout and/or stderr
unscathed:

Code Sample 3:

    #!/bin/bash
    ( ( (
	for x in 1 2
	do
		trap continue PIPE      # reduce broken pipe screeching
		cat /etc/termcap        # a big text file
	done | sed 1q
    ) 1>&3 ) 2>&1 | grep -vxF 'Broken pipe' 1>&2 ) 3>&1

The following patch to bash jobs.c will enable "Code Sample 2" to do the
right thing, without depending (so much) on the DONT_REPORT_SIGPIPE
compile time flag.  With this patch, you don't have to go all the way to
the baroque code in "Code Sample 3" to shut bash up.  Just a well placed
trap is sufficient.

Whether or not this is actually worth persuing (or was even worth
reading ;) I don't know.

--- jobs.c.orig 2001-03-26 10:08:24.000000000 -0800
+++ jobs.c      2005-04-29 17:09:44.294763496 -0700
@@ -2686,11 +2686,8 @@ notify_of_job_status ()
                }
              else if (IS_FOREGROUND (job))
                {
-#if !defined (DONT_REPORT_SIGPIPE)
-                 if (termsig && WIFSIGNALED (s) && termsig != SIGINT)
-#else
-                 if (termsig && WIFSIGNALED (s) && termsig != SIGINT && termsig != SIGPIPE)
-#endif
+                 if (termsig && WIFSIGNALED (s) && termsig != SIGINT &&
+                   (termsig != SIGPIPE || signal_is_trapped (termsig) == 0))
                    {
                      fprintf (stderr, "%s", strsignal (termsig));



-- 
                  I won't rest till it's the best ...
                  Programmer, Linux Scalability
                  Paul Jackson <pj@engr.sgi.com> 1.650.933.1373, 1.925.600.0401
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Received on Sat Apr 30 10:22:55 2005

This archive was generated by hypermail 2.1.8 : 2005-04-30 10:22:55 EST