I have a file test.txt
and have no file named test
. When I tried
ls test test.txt > new 2>new
I was expecting new
to be overwritten since >>
is not used. But in the output file I got both contents appended. Why is it so?
bashdebianio-redirectionls
I have a file test.txt
and have no file named test
. When I tried
ls test test.txt > new 2>new
I was expecting new
to be overwritten since >>
is not used. But in the output file I got both contents appended. Why is it so?
Best Answer
TL;DR
bash
opens and truncates all involved files before anything is written to them.stdout
andstderr
are both sent tonew
becausebash
has already truncated the file (twice) whenls
starts printing.This is how
bash
prepares/handles I/O redirection. When you ask for a command to be redirected (>
) to a file,bash
basically opens that file, creating it if necessary. If the file already exists, it is truncated. This is done through theopen
system call and a few flags, in your case:O_CREAT
creates the file if it does not exist, whileO_TRUNC
truncates it when it does. Thisopen
system call is part ofbash
's initialisation for redirection, meaning that when you use several redirection operations, such as in......
bash
begins by opening all concerned files. Therefore, before runningls
, it opensnew
twice, with the same flags:This means that basically, when running your command,
bash
does the following (in that order) :new
as standard output, create/truncate the file when necessary.new
as standard error, create/truncate the file when necessary.ls
: this will write contents tonew
.As you can see,
bash
truncates all involved files before startingls
. This means that when running something with... >new 2>new
,new
is basically truncated "twice", and then, outputs are redirected to it. The behaviour you are expecting would requirebash
to capturels
's stdout and stderr independently, and to open them one after the other, just before writing. Basically:ls
.stdout
, opennew
, truncate it and write to it.stderr
, opennew
again, truncate it, and write to it.However, messages may come out interweaven: the redirected program might very well write something to
stdout
, then something else tostderr
, and then back onstdout
... It would be horrible to manage all of that (and it might lead to undesirable (undefined?) behaviours...).