how to redirect in bash+crontab

how to redirect in bash+crontab

Amos Shapira amos.shapira at gmail.com
Tue Jul 24 16:06:17 IDT 2012


For the platforms which use a pipe for /dev/stderr try running fuser to see
what else has it open. I suspect it would be something like a "mail"
process initiated by cron.

In general, /dev/stderr is not a standard, not portable and IMHO shouldn't
be relied on.

The shell does exactly what is expected - the "special case" you ask for is
the &2 syntax and /dev/stderr is a hack to let you treat stderr as a
regular file.

I don't see what needs to be changed except the curiosity of /dev/stderr
not working any more, it might also be related to /dev being a special file
system which could create entries dynamically (sorry, I'm writing this from
home, I might remember to test this on our work servers tomorrow).

--Amos

On 24 July 2012 18:52, Oleg Goldshmidt <pub at goldshmidt.org> wrote:

> Hi,
>
> I thought I'd share an observation that was, I admit, new to me - and I
> thought I had plenty of experience. And then I have a question or two.
>
> I moved a bunch of scripts to a new computer (RHEL 5.4 -> CentOS 6.2).
> They work, but I noticed weird "permission denied" messages in the mails
> cron sends. Turns out that I had functions wrapping "real" bash code in
> progress messages that produce output like
>
> Doing XYZ ... done [or "Doing XYZ ... failed", or whatever is appropriate]
>
> Since the real output was sometimes redirected to files these messages are
> sent to stderr.
>
> Surprise! It all worked for years on RHEL 5.4. On CentOS 6.2, however, it
> works flawlessly from the command line, but NOT from crontab! At least
> stuff like
>
> echo "fubar" > /dev/stderr
>
> does not. At the same time,
>
> echo "fubar" >&2
>
> works perfectly both interactively and through crontab. [The functional
> part of the scripts works fine - the errors come from those progress
> messages, but it's immaterial here.]
>
> On RHEL 5.4, CentOS 6.2, and Fedora 15 (my laptop) /dev/stderr is a
> symlink to /proc/self/fd/2 (which is what you'd expect). I wrote a little
> script that prints "ls -nld" and "ls -nldL" of /proc/self/fd/2 as well as
> the real and effective user and group IDs of the process, and ran the
> script interactively and from crontab on all three systems. Here is what I
> discovered.
>
> RHEL 5.4 (my uid is 500 and my gid is 500, gid 5 is "tty"):
>
> -----------------------------------------------------------------------------------------------
>
> interactive:
> lrwx------ 1 500 500 64 Jul 24 10:39 /proc/self/fd/2 -> /dev/pts/1
> crw--w---- 1 500 5 136, 1 Jul 24 10:39 /proc/self/fd/2
>
> crontab:
> l-wx------ 1 500 500 64 Jul 24 10:40 /proc/self/fd/2 -> pipe:[27443942]
> prw------- 1 500 500 0 Jul 24 10:40 /proc/self/fd/2 # [OG] I am the owner!
>
> CentOS 6.2 (my uid is 500, gid is 501, group 5 is "tty" again):
>
> ------------------------------------------------------------------------------------------------------
>
> interactive:
> lrwx------ 1 500 501 64 Jul 24 10:39 /proc/self/fd/2 -> /dev/pts/0
> crw--w---- 1 500 5 136, 0 Jul 24 10:39 /proc/self/fd/2
>
> crontab:
> l-wx------ 1 500 501 64 Jul 24 10:27 /proc/self/fd/2 -> pipe:[3750679]
> prw------- 1 0 501 0 Jul 24 10:27 /proc/self/fd/2     # [OG] the owner is
> root! I can't write to it!
>
> Fedora 15 (my uid is 500, gid is 500, gid 5 is "tty"):
>
> ------------------------------------------------------------------------------------
>
> interactive:
> lrwx------ 1 500 500 64 Jul 24 11:08 /proc/self/fd/2 -> /dev/pts/2
> crw------- 1 500 5 136, 2 Jul 24 11:08 /proc/self/fd/2
>
> crontab:
> l-wx------ 1 500 500 64 Jul 24 10:37 /proc/self/fd/2 -> pipe:[47022]
> prw------- 1 0 500 0 Jul 24 10:37 /proc/self/fd/2 # [OG] the owner is
> root! I can't write to it!
>
> So, when run from crontab stderr is actually a pipe. On RHEL 5.4 the pipe
> belongs to the actual user and is writeable. On 6.2 and Fedora the pipe
> belongs to root and is not writeable by the user.
>
> When run interactively, stderr is linked to a character device (tty) that
> is writeable by the user. For some reason, on Fedora the device is not
> writeable by group tty, while on RHEL/CentOS it is.
>
> I think I understand WHAT is happening, e.g., redirecting to /dev/stderr
> causes the system to check the file/fifo permissions against the effective
> uid and since they are insufficient, fail. At the same time, doing >&2 does
> not cause checking filesystem permissions, and hence works. I did strace in
> both cases and ">/dev/stderr" does open(2) and then dup2(2), whereas ">&2"
> does only dup2(2).
>
> However, I have a lingering feeling that both redirections should work the
> same. I expect them to be functionally equivalent (though maybe it's naive
> of me). I also do not understand WHY the behaviour changed.
>
> Is it a bug? If so, is it a kernel bug (it creates the /proc hierarchy,
> right?) or a cron bug (faulty effective id?) or a bash bug (should
> /dev/stderr be handled specially)? Were there (security?) reasons to change
> the ownership of the pipe (and permissions on the character tty device in
> Fedora, while we are at it)?
>
> Until it is resolved one way or another it looks like ">&2" is much
> preferable to ">/dev/stderr". I find it quite unexpected. I actually like
> /dev/stderr better since it is less cryptic.
>
> --
> Oleg Goldshmidt | pub at goldshmidt.org <oleg at goldshmidt.org>
>
> _______________________________________________
> Linux-il mailing list
> Linux-il at cs.huji.ac.il
> http://mailman.cs.huji.ac.il/mailman/listinfo/linux-il
>
>


-- 
 [image: View my profile on LinkedIn]
<http://www.linkedin.com/in/gliderflyer>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.cs.huji.ac.il/pipermail/linux-il/attachments/20120724/6380ae5e/attachment.html>


More information about the Linux-il mailing list