3

Can you please explain me why:

cat < file.txt > file.txt

makes file.txt empty?

This is observed in Bash in Linux.

2
  • Just to add to the bottom two answers: if you wanted to make a loop (endlessly filling file) you could type cat <file.txt >>file.txt as two >> mean appending to instead of deleting the file.
    – GregC
    Dec 22, 2009 at 6:32
  • Yikes. That's just scary. I've never even thought of using (abusing?) cat and pipes like that! That's why we have the "touch" command. ;-) Makes for a cool example though. Jan 6, 2010 at 20:29

3 Answers 3

16

Because it opens and truncates the file before reading the data — it being shell, the redirections are processed by shell before even starting cat.

13

The > redirection happens first and opens file.txt for writing which clears any existing content.

1
  • 1
    This answer is somewhat misleading -- @hacker's is more precise. On my systems, the redirections are processed in order of specification. That is, < 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.
    – pilcrow
    Feb 8, 2010 at 22:20
1

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.

1
  • 1
    (1) Welcome to Super User. The question is old, answered long ago, but your answer contains technical details not present in the old answers. Nice debut. (2) "different shells may have different implementations" – It's worth noting that for many shells these possibly "different implementations" lead to the same result. The behavior is standard, mandated by POSIX, very common. Even 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

You must log in to answer this question.