Skip to main content
added 438 characters in body
Source Link
ilkkachu
  • 148.2k
  • 16
  • 268
  • 441

Not sure it's that well known, but it happens because done like that, the two file handles are completely separate, and have independent read/write positions. Hence they can overwrite each other. (They correspond to two distinct open file descriptions, to use the technical term, which is sadly somewhat easy to confuse with the term "file descriptor".)

This only happens with foo > out.txt 2>out.txt, not with foo > out.txt 2>&1, since the latter copies the file descriptor (referring to the same open file description).

When appending, all writes go the to end of the file, as it is during the moment of the write. This is handled by the OS, atomically, so that there's no way for even another process to get in the middle. Hence, the issue from independent read/write positions is defused. (Except it might not work over NFS, that's a filesystem restriction.)

In your example, the error message ls: cannot access... is written first, at the start of the file. The write position of the stderr fd is now at the end of the file. Then the regular output of file.txt<newline> is also written, but the write position of the stdout fd is still at the start, so those 9 bytes overwrite part of the error message.

With an appending fd, that second write would go to end, regardless of anything.

Not sure it's that well known, but it happens because done like that, the two file handles are completely separate, and have independent read/write positions. Hence they can overwrite each other. (They correspond to two distinct open file descriptions, to use the technical term, which is sadly somewhat easy to confuse with the term "file descriptor".)

This only happens with foo > out.txt 2>out.txt, not with foo > out.txt 2>&1, since the latter copies the file descriptor (referring to the same open file description).

When appending, all writes go the to end of the file, as it is during the moment of the write. This is handled by the OS, atomically, so that there's no way for even another process to get in the middle. Hence, the issue from independent read/write positions is defused. (Except it might not work over NFS, that's a filesystem restriction.)

Not sure it's that well known, but it happens because done like that, the two file handles are completely separate, and have independent read/write positions. Hence they can overwrite each other. (They correspond to two distinct open file descriptions, to use the technical term, which is sadly somewhat easy to confuse with the term "file descriptor".)

This only happens with foo > out.txt 2>out.txt, not with foo > out.txt 2>&1, since the latter copies the file descriptor (referring to the same open file description).

When appending, all writes go the to end of the file, as it is during the moment of the write. This is handled by the OS, atomically, so that there's no way for even another process to get in the middle. Hence, the issue from independent read/write positions is defused. (Except it might not work over NFS, that's a filesystem restriction.)

In your example, the error message ls: cannot access... is written first, at the start of the file. The write position of the stderr fd is now at the end of the file. Then the regular output of file.txt<newline> is also written, but the write position of the stdout fd is still at the start, so those 9 bytes overwrite part of the error message.

With an appending fd, that second write would go to end, regardless of anything.

Source Link
ilkkachu
  • 148.2k
  • 16
  • 268
  • 441

Not sure it's that well known, but it happens because done like that, the two file handles are completely separate, and have independent read/write positions. Hence they can overwrite each other. (They correspond to two distinct open file descriptions, to use the technical term, which is sadly somewhat easy to confuse with the term "file descriptor".)

This only happens with foo > out.txt 2>out.txt, not with foo > out.txt 2>&1, since the latter copies the file descriptor (referring to the same open file description).

When appending, all writes go the to end of the file, as it is during the moment of the write. This is handled by the OS, atomically, so that there's no way for even another process to get in the middle. Hence, the issue from independent read/write positions is defused. (Except it might not work over NFS, that's a filesystem restriction.)