<div dir="ltr"><font face="georgia,serif">Hi,<br><br><span style="font-family:georgia,serif">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.</span><br style="font-family:georgia,serif">
<span style="font-family:georgia,serif"> </span><br style="font-family:georgia,serif"><span style="font-family:georgia,serif"></span><span style="font-family:georgia,serif">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</span><br style="font-family:georgia,serif">
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">Doing XYZ ... done [or "Doing XYZ ... failed", or whatever is appropriate]</span><br style="font-family:georgia,serif"><br style="font-family:georgia,serif">
<span style="font-family:georgia,serif">Since the real output was sometimes redirected to files these messages are sent to stderr.</span><br style="font-family:georgia,serif"><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">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</span><br style="font-family:georgia,serif">
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">echo "fubar" > /dev/stderr </span><br style="font-family:georgia,serif"><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">does not. At the same time,</span><br style="font-family:georgia,serif">
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">echo "fubar" >&2</span><br style="font-family:georgia,serif"><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">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.]</span><br style="font-family:georgia,serif" clear="all">
</font><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">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.</span><br style="font-family:georgia,serif" clear="all">
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">RHEL 5.4 (my uid is 500 and my gid is 500, gid 5 is "tty"):</span><br style="font-family:georgia,serif">-----------------------------------------------------------------------------------------------<br>
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">interactive:</span><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">lrwx------ 1 500 500 64 Jul 24 10:39 /proc/self/fd/2 -> /dev/pts/1</span><br style="font-family:georgia,serif">
<span style="font-family:georgia,serif">crw--w---- 1 500 5 136, 1 Jul 24 10:39 /proc/self/fd/2</span><br style="font-family:georgia,serif"><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">crontab:</span><br style="font-family:georgia,serif">
<span style="font-family:georgia,serif">l-wx------ 1 500 500 64 Jul 24 10:40 /proc/self/fd/2 -> pipe:[27443942]</span><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">
prw------- 1 500 500 0 Jul 24 10:40 /proc/self/fd/2 # [OG] I am the owner!</span><br style="font-family:georgia,serif">
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">CentOS 6.2 (my uid is 500, gid is 501, group 5 is "tty" again):</span><br style="font-family:georgia,serif">------------------------------------------------------------------------------------------------------<br>
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">interactive:</span><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">lrwx------ 1 500 501 64 Jul 24 10:39 /proc/self/fd/2 -> /dev/pts/0</span><br style="font-family:georgia,serif">
<span style="font-family:georgia,serif">crw--w---- 1 500 5 136, 0 Jul 24 10:39 /proc/self/fd/2</span><br style="font-family:georgia,serif"><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">crontab:</span><br style="font-family:georgia,serif">
<span style="font-family:georgia,serif">l-wx------ 1 500 501 64 Jul 24 10:27 /proc/self/fd/2 -> pipe:[3750679]</span><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">prw------- 1 0 501 0 Jul 24 10:27 /proc/self/fd/2 # [OG] the owner is root! I can't write to it!</span><br style="font-family:georgia,serif">
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">Fedora 15 (my uid is 500, gid is 500, gid 5 is "tty"):</span><br style="font-family:georgia,serif">------------------------------------------------------------------------------------<br>
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">interactive:</span><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">lrwx------ 1 500 500 64 Jul 24 11:08 /proc/self/fd/2 -> /dev/pts/2</span><br style="font-family:georgia,serif">
<span style="font-family:georgia,serif">crw------- 1 500 5 136, 2 Jul 24 11:08 /proc/self/fd/2</span><br style="font-family:georgia,serif"><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">crontab:</span><br style="font-family:georgia,serif">
<span style="font-family:georgia,serif">l-wx------ 1 500 500 64 Jul 24 10:37 /proc/self/fd/2 -> pipe:[47022]</span><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">prw------- 1 0 500 0 Jul 24 10:37 /proc/self/fd/2 # [OG] the owner is root! I can't write to it!</span><br style="font-family:georgia,serif">
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">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.</span><br style="font-family:georgia,serif">
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">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.</span><br style="font-family:georgia,serif">
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">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).</span><br style="font-family:georgia,serif">
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">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.</span><br style="font-family:georgia,serif">
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">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)?</span><br style="font-family:georgia,serif">
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">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. </span><br style="font-family:georgia,serif">
<br style="font-family:georgia,serif"><span style="font-family:georgia,serif">-- </span><br style="font-family:georgia,serif"><span style="font-family:georgia,serif">Oleg Goldshmidt | </span><a style="font-family:georgia,serif" href="mailto:oleg@goldshmidt.org" target="_blank">pub@goldshmidt.org</a><br>
</div>