Is it safe to redirect stdout and stderr to the same file without file descriptor copies

io-redirectionstderrstdout

I start off in empty directory.

$ touch aFile
$ ls
aFile

Then I ls two arguments, one of which isn't in this directory. I redirect both output streams to a file named output. I use >> in order to avoid writing simultaneously.

$ ls aFile not_exist >>output 2>>output
$ cat output
ls: cannot access 'not_exist': No such file or directory
aFile

Which seems to work. Are there any dangers to this approach?

Best Answer

No, it's not just as safe as the standard >>bar 2>&1.

When you're writing

foo >>bar 2>>bar

you're opening the bar file twice with O_APPEND, creating two completely independent file objects[1], each with its own state (pointer, open modes, etc).

This is very much unlike 2>&1 which is just calling the dup(2) system call, and makes the stderr and stdout interchangeable aliases for the same file object.

Now, there's a problem with that:

O_APPEND may lead to corrupted files on NFS filesystems if more than one process appends data to a file at once. This is because NFS does not support appending to a file, so the client kernel has to simulate it, which can't be done without a race condition.

You usually can count on the probability of the file like bar in foo >>bar 2>&1 being written to at the same time from two separate places being quite low. But by your >>bar 2>>bar you just increased it by a dozen orders of magnitude, without any reason.

[1] "Open File Descriptions" in POSIX lingo.

Related Question