10

Here's how to reproduce it:

echo 'the original file' > orig
ln -s orig symb # now symb is symlinked to orig
cat symb > orig # this makes orig an EMPTY FILE, but why?

orig becomes an empty file after the third command, but why?

Teddy C
  • 457
  • 7
    Your command is exactly the same as cat orig >orig. Are you thinking you're doing something different? – Kusalananda Feb 19 '21 at 13:57
  • 11
    I think you are victim to the misconception that the cat command performs the redirection. If this is what you think, you are wrong. It is the shell. Before executing cat, the shell processes > orig. This means that it creates an empty orig if it doesn't exist, or it resets orig to a size of 0 if it exists. After that, cat is called, its stdout connected to orig. – berndbausch Feb 19 '21 at 14:24
  • Cf. https://stackoverflow.com/questions/6696842/how-can-i-use-a-file-in-a-command-and-redirect-output-to-the-same-file-without-t. "The reason why you can't do that: bash processes the redirections first, then executes the command. So by the time grep looks at file_name, it is already empty." – BallpointBen Feb 20 '21 at 04:58

1 Answers1

30

Symlinks are evaluated as you attempt to open a file. Under "normal" circumstances the result of opening a symbolic link is to open the file it references. So:

ln -s original_file my_symlink
cat my_symlink > original_file

Is very similar to:

cat original_file > original_file

Why does it destroy the content?

In any shell command > some_file will first open and truncate (zero) some_file and then execute command, writing the result to some_file.

So if you cat x > x then the shell will open and truncate x, then cat x will open and read the truncated file writing all of it's zero bytes.

Mutantoe
  • 161