Can you please explain me why:
cat < file.txt > file.txt
makes file.txt
empty?
This is observed in Bash in Linux.
Because it opens and truncates the file before reading the data — it being shell, the redirections are processed by shell before even starting cat
.
The >
redirection happens first and opens file.txt
for writing which clears any existing content.
<
happens first, and then >
, but the latter opens not merely "for writing" but with truncation (O_TRUNC
), which is what "clears existing content." @hacker is right, this happens before cat(1)
is even executed.
The following is an example of Bash
, where we assume the filename is file.txt
. Note that different shells may have different implementations.
Redirections are processed in the order they appear, from left to right.
So it's not because of which "happens first".
The pseudo-code to accomplish STDIN_FILENO = 0
is as follows
fd = openat(AT_FDCWD, "file.txt", O_RDONLY);
dup2(fd, STDIN_FILENO);
close(fd);
The pseudo-code to accomplish STDIN_FILENO = 1
is as follows
fd = openat(AT_FDCWD, "file.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
dup2(fd, STDOUT_FILENO);
close(fd);
These occur sequentially before the cat
is executed.
For the following two ways:
cat < file > file
cat > file < file
The difference is only in the order in which the pseudocode executes both.
O_TRUNC
If the file already exists and is a regular file and the access mode allows writing (i.e., is O_RDWR or O_WRONLY) it will be truncated to length 0.
Not surprisingly, if you specify output redirection, the contents of file.txt
will be cleared during the opening of the file.
zsh
(that deviates from POSIX standard where it finds the standard goofy or harmfully surprising) does redirections this way.
Oct 21, 2023 at 7:58
file
) you could typecat <file.txt >>file.txt
as two >> mean appending to instead of deleting the file.