how to redirect in bash+crontab

how to redirect in bash+crontab

Oleg Goldshmidt pub at goldshmidt.org
Wed Jul 25 01:27:11 IDT 2012


"Nadav Har'El" <nyh at math.technion.ac.il> writes:

> No, this cannot happen. write(2) cannot fail because of permission
> problems, only the open(2) can. 

Actually, if the file was not open for writing write(2) will return
EBADF. ;-)

While there are, indeed, many ways to acquire a fd the "normal" case,
e.g., for

echo "fubar" > $HOME/tmp/myfakestdout

(this is same as my redirecton, only with a "real" file on a disk)
involves an open() call and a dup2(3,1) (assuming open() returns 3).

If you do not have write permissions on the file open() will return
EACCESS and you will see "Permission denied" on your stderr stream. 

> Like I explained, they *can't* be done right (when right mean "just
> like dup(2) would work) when it comes to ordinary files (not pipes).
>
> The only way to do this right, as far as I can see, is for
> /dev/stderr and friends *not* to be symbolic links.

Sorry, I don't really see what symlinks have to do with it. I think
/dev/stderr and friends have been symlinks since forever (even Stevens
says so, and, sadly, he passed away years ago), and everything worked
just fine when

* /dev/stderr was a symlink to /dev/fd/2
* /dev/stderr is a symlink to a tty character device
* /dev/stderr was a symlink to a pipe with appropiate ownership

The problem *only* occurs when /dev/stderr is a symlink to a pipe
owned by a different user (root, specifically), and while group
ownership is appropriate there is no group write permission.

I think the "symlink" and "pipe" parts are irrelevant, as is the
"using open()" part - these are just implementation details. After
all, even for the good old /dev/fd/2 there was an open() call, the
special implementation part was that the mode argument was ignored.

Incidentally, if I read Stevens right this had nothing to do with bash
- the behaviour would be the same if you opened /dev/fd/* in your
own code as well. Or if you opened /dev/stderr in your own code. As
far as I understand this special treatment was built into open(2).

I didn't immediately see anything special in the logic of, say,
do_filp_open() in the kernel's fs/namei.c. As far as I could see
symlinks are followed unil resolved (the branch labeled "do_link") and
then the real work is done (the "do_last" label). At some point there
is a check for special_file (in do_dentry_open() in fs/open.c) but
this checks whether the file is a character device or a block device
or a pipe or a socket and seems intended for some sort of bookkeeping
rather than actively ignoring the mode (which would not sound
logical). Not sure - too tired.

As I mentioned before, doing nothing special would be, in fact,
elegant, but then it shouldn't fail... ;-)

I am inclined to suspect that the pipe that the kernel creates has
wrong ownership/permissions, and if/when that is fixed everything will
be sane again.

-- 
Oleg Goldshmidt | pub at goldshmidt.org



More information about the Linux-il mailing list