Take the tour ×

Cron executes whatever program is sent to it in such a fashion that anything written to STDERR causes either the kernel (or cron I'm unsure) to receive SIGPIPE. How does this functionality work? Is cron sending SIGPIPE or is the kernel? How can I get that same effect, without running something in cron? Could someone tell me for instance how to run a Perl script such that

#!/usr/bin/env perl
warn 'foo';
print "bar;

Receives a SIGPIPE when it tries to write 'foo' to STDERR, and never writes 'bar'? I want to see Perl terminate and shell variable $? return 255.

share|improve this question
Cron is supposed to collect stdout/stderr and mail it to whoever started the run... –  vonbrand Mar 7 at 21:00
Show us your crontab line. –  Gilles Mar 7 at 23:54
add comment

2 Answers

You can do that by redirecting STDERR to the write-end of a pipe, then closing the read end:

#!/usr/bin/env perl
pipe R,STDERR;
close R;
warn 'foo';
print "bar";
share|improve this answer
add comment

"How does this functionality work?"

What you are describing is not really functionality, it's dysfunctionality caused by a misconception. It's not cron that sends the SIGPIPE, but it is because of the way you are using it.

By default cron emails the stdout and stderr of a process to the owner of the crontab using sendmail (see man cron; if you don't have an MTA installed, the output is just discarded), unless they are redirected. To do this, it must wait for the process to complete. However, if you have backgrounded the process with &:

* * * * * /bin/someprogram &

It won't wait, and if the program now tries to write to stdout or stderr, it will get a SIGPIPE, because the pipe is broken (the read end was closed). [This might also happen to a non-background process on older crons if your MTA is missing and you have a lot of output]

So I am going to guess that you have something like this in your crontab:

* * * * * /bin/someprogram > log.file &

Meaning the stdout is redirected to a file, but the stderr pipe is still broken. This has led you to the erroneous conclusion that "cron executes whatever program is sent to it in such a fashion that anything written to STDERR causes ... SIGPIPE".

You can fix your crontab by either removing the backgrounding & or redirecting stderr too:

* * * * * /bin/someprogram 1>&2&> log.file &

If you want. WRT duplicating this yourself, as qqx says, just close one end of a pipe and then write to it.

share|improve this answer
I don't have & in my crontab, I call a shell script redirrecting stderr to stdout 2>&1. That shell script launches a Perl script with no redirrections whatsoever. What that perl script issues a warning, it dies with 255. –  Evan Carroll Mar 7 at 21:15
@EvanCarrol : Fair enough, so it's either the sendmail issue or the relationship between the shell script and the perl script. You didn't post either of those things or the crontab, so I can't say. However, in any case, the SIGPIPE happening is accidental -- that's not how cron is intended to function. –  goldilocks Mar 7 at 21:20
The above did nothing, it worked fine. I just can't why whatever I'm doing does not run in Cron. –  Evan Carroll Mar 7 at 21:26
As long as you are aware that this is a sign something is not right. If you want to diagnose the problem further, you should ask another question and/or post some of the stuff involved. –  goldilocks Mar 7 at 21:33
In my syslog it says, (CRON) info (No MTA installed, discarding output), I wonder if that means cron throws SIGPIPE anytime either STDERR or STDOUT isn't redirrected and something appears on those streams.. –  Evan Carroll Mar 7 at 22:04
show 1 more comment

Your Answer


