James wrote: > Given this explanation, it's probably not a great idea to use > signal.signal() then. ;)
In this case, it seems to me that setting the SIG_DFL action for SIGPIPE is precisely what one would want to do. This is pure speculation, but if you were to re-implement some of the subprocess module functionality for a similar task (using the os module methods for processes and pipes), you could wrap the appropriate calls in a try/except to trap a broken pipe. IIUC, this is exactly the reason python sets SIGPIPE signals to SIG_IGN (see the signal module docs: http://docs.python.org/lib/module-signal.html). A casual attempt appears to reveal that the subprocess module swallows these exceptions. I hope I'm wrong, because I tend to think that trapping with a try/except would be the preferred approach to this problem. Perhaps someone can confirm, or help to clarify? My previous signal example was a bit careless. I agree with Alan, it's seems best to exercise some caution when messing with signals. It may be safer to restrict the sigpipe signal changes to processes only when you need to. Fortunately, you can accomplish this by passing a function as the preexec_fn argument to subprocess 'call', 'Popen', and perhaps others. Consider the following (credit to Matthew Woodcraft, posted to the python-dev list in Jul 2007): import signal import subprocess as sp def permit_sigpipe(): signal.signal(signal.SIGPIPE, signal.SIG_DFL) # no broken pipe, preexec_fn is called inside the child process # thus setting sigpipe/sig_dfl for this process only sp.call("yes 'Spam' | head -n 10", shell=True, preexec_fn=permit_sigpipe) # oops, we should get a broken pipe message sp.call("yes 'Spam' | head -n 10", shell=True) > > Any other thoughts? I've tried about redirecting my output using > subprocess.Popen( ... , stdout=*something* ), but I haven't had much > luck. The error still appears. Or should I be redirecting the > "stderr" instead of "stdout"? yes :) but only stderr of the 'yes' command. If the 'make oldconfig' command writes to stderr I presume you want to see it. > > Any ideas on how to use subprocess.Popen() to make this lovely little > error disappear? > Use two Popen objects, redirect stderr from the left-side process ('yes') to /dev/null (or a log file, if you want to inspect), and connect stdin of right-side process ('make oldconfig') to stdout of the left-side by way of a subprocess.PIPE. Here's an example: import subprocess as sp # replace /dev/null below to a path of your choosing # to send stderr to a file for later review leftside = sp.Popen("yes ''", shell=True, stdout=sp.PIPE, stderr=file('/dev/null', 'w')) rightside = sp.Popen('make oldconfig', shell=True, stdin=leftside.stdout) IMHO, I think this approach is 'ok' for your purposes, since you are unlikely to care about most stderr messages from 'yes'. However, I wouldn't recommend it as a general practice. Also beware, if you do this ... import subprocess as sp sp.call("yes '' | make oldconfig", shell=True, stderr=file('/dev/null', 'w')) ... stderr from 'make oldconfig' will be sent to /dev/null as well. HTH, Marty > Thanks! > .james > > On Oct 20, 2007, at 7:34 PM, Alan Gauld wrote: > >> "James" <[EMAIL PROTECTED]> wrote >> >>> signal.signal(signal.SIGPIPE, signal.SIG_DFL) >>> >>> Before the snippet of code I included in my original e-mail >>> (subprocess.call( "yes '' | make oldconfig" , shell=True )) got rid >>> of the error. I can't seem to figure out precisely what the >>> signal.signal() function does (as shown above). >> A signal is basically an interrupt. Its raised by the OS. >> signal.signal catches the named signal(s) and handles it. >> The default handler appears to just swallow the signal >> silently. >> >> Its a bit like, in Python, doing >> >> try: someFunc() >> except SomeError: pass >> >> The except clause catches the error but ignores it. >> >> signal.signal is doing much the same but at the OS level. >> >> My personal approach is to avoid using signal to trap >> and ignore signals since they can be needed by other >> processes running concurrently on the machine, >> but in this case it appears harmless. But in general, >> any approach which could interfere in unpredicable >> ways with other processes on the computer is a >> risky strategy IMHO. >> >> HTH, >> >> Alan G. _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor