In many Linux books is written that 'redirection is executed before a command'. Let's consider:
$ cat bar
hello
$ ecno "foo" > bar
bash: ecno: command not found
$cat bar
- If bar would not exist, redirection would created it.
- If bar exists and a command did not work, it erases the content of bar.
But it does not copy any output into bar (since there is no output), so it should be said 'redirection is executed PARTIALLY before a command', since the one part of '>' did not work here, namely copying the output of the command into a file bar. Is it right?
From bash manual section 3.6.2:
Redirection with
> file
always truncates file before executing command, which means contents are erased regardless of the output; the actual writing to file will take place if there is an actual output (most notably observed with the lack ofwrite()
call instrace -f -e open,dup2,write bash -c 'true > out2.txt'
) and if no further error occurs.Therefore, everything works properly, as per specifications, and the wording is correct. In fact this behavior is specified by POSIX Shell Command Language specifications and is supported by all POSIX-compliant shells, including
ksh
anddash
(aka Ubuntu's/bin/sh
, see the related question).On the system level, redirection is performed by dup family of system calls, which is why redirection is formally called duplicating file descriptors and is most prominent when we perform the
>/dev/null 2&>1
type of redirection.It can be observed with
strace
command in the following example of successful and failed command. Note how the files are opened withO_CREAT|O_TRUNC
flag.Well, the second part worked, in that it copied the empty output into the file.
For instance, if you redirect stderr with
2>
instead of stdout, you'll see that the error makes it into that file:And the contents of "bar" are updated to:
The fact that the file gets truncated is part of how the redirection works too.
I hope this helps you make sense of how redirection works!