how to redirect in bash+crontab
Oleg Goldshmidt
pub at goldshmidt.org
Tue Jul 24 19:40:39 IDT 2012
On Tue, Jul 24, 2012 at 6:50 PM, Nadav Har'El <nyh at math.technion.ac.il>wrote:
>
> This is a very interesting analysis, which I've never considered before.
>
> With pipes, we can perhaps argue the owner is wrong - that we're talking
> about a "fake" file so Linux could have invented a different owner for
> it.
>
Everything is a file, as we know, even a pipe. The ownership is important,
and was switched from (presumably) the euid to 0 at some point, causing the
described problem. I don't know why and I'd like to know. or maybe it's a
bug?
> However, there's an even bigger problem I think: Consider a situation
> where /proc/self/fd/2 points not to a pipe, but to an on-disk file:
>
> This file may belong to another user - it could have been passed to the
> current process by inheritance, or over a unix-domain socket or
> whatever. The current process *is* able to use the file descriptor, but
> it won't be able to open /proc/self/fd/2. And this can't even be fixed
> because the file this points to has certain owner and permission bits,
> and the kernel can't mess with those (like it theoretically could with the
> fake pipe file in your example).
>
Isn't it the same as redirecting stderr to a real file and finding out that
you don't have permissions to write to it?
> I do think this is a logic bug, and the reason why it came to be is,
> I believe, the following:
>
> Old versions of Unix following 8th Edition Research Unix had a similar
> feature called /dev/fd/... (see http://man.cat-v.org/unix_8th/4/fd).
> There was a small, but for your purpose very important, difference
> between how /dev/fd worked then, and how /proc/self/fd/... works in
> Linux. "/dev/fd/2" wasn't a symbolic link (symbolic links were new to
> Unix at the time, and were not commonly used in any case). It was a
> special device (you had just 127 of them). When any process open()ed
> this device, the open would always succeed - the manual specified that
> open("/dev/fd/n", mode) is identical to dup(n). No additional permission
> testing would be done. /dev/fd/2 (and the identical /dev/stderr) would
> work exactly like you wanted.
>
[By this time I have already grabbed a copy of APUE from a colleague's desk
and found all of the above written there, including the statement that
/dev/stderr was equivalent to /dev/fd/2. In fact, if memory serves, in the
dark bygone days - possibly in the previous millennium - /dev/stderr used
to be a symlink to /dev/fd/2. My memory has been noticed to be faulty
occasionally in the past.]
This is exactly the difference - /dev/fd/2 was "special" and today's
/dev/stderr is not. I generally subscribe to the philosophy of having as
few special cases as possible, so treating /dev/stderr as a regular file
(with open(), etc) rather than as a special file actually appeals to my
sense of aesthetics. But then care should be taken not to fail where
failure is not expected - in this case, permissions should be right.
[There may, theoretically, be a good security reason why the pipe belongs
to root now, but I am not aware of any.]
> Linux deviated from this implementation for several reasons, one of them
> being that is a cool feature to do "ls -l /proc/self/fd" and see the
> names of all the open files. (there are several other important reasons
> that we can discuss if you want). This alternative implementation broke
> the correct behavior that Unix's /dev/fd/2 had - as you discovered.
>
> I don't know if Linux should be fixed at this point, as so much water
> has passed under the bridge since Unix implemented /dev/stderr
> correctly. I think /dev/stderr (and stdin, stdout) at least could
> easily have been fixed - even if the rest of /proc/fd is more difficult
> to fix.
>
> But I think it's important that this caveat is documented in proc(5),
>
And in bash(1), as I pointed out in my reply to Amos.
>
> I remember when I learned Unix, it took me a while to understand what
> the strange incantations like
>
> something >filename 2>&1
>
> actually did. But when I finally understood how it works (i.e., uses
> dup(2)), I never had any problem with this syntax.
I do not have any problem with the syntax. I do have to work with other
people and less experienced folks may - and do - have problems with the
admittedly rather arcane rules. Doing ">/dev/stderr" is much clearer and
cleaner and readily readable and understandable (to say nothing of being
very similar to g?awk that is so often used together with shell scripts -
there "/dev/stderr" *is* treated specially). The desire to express myself
clearly and cause as little confusion as possible led me to prefer
">/dev/stderr".
> And understanding
> what these do is important, because the authors of CSH obviously didn't
> and thus completely ruined that shell's redirection capabilities
> (see the very first entry in
> http://www.faqs.org/faqs/unix-faq/shell/csh-whynot/ )
>
Don't start... ;-)
--
Oleg Goldshmidt | pub at goldshmidt.org <oleg at goldshmidt.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.cs.huji.ac.il/pipermail/linux-il/attachments/20120724/98e6bc9c/attachment-0001.html>
More information about the Linux-il
mailing list