3

Given a file, foo.txt:

1
2
3
4
5

Say we want to change it to contain:

1
2
3

Why does head -n3 foo.txt > foo.txt leave foo.txt empty?

cantlin
  • 141
  • 3

1 Answers1

10

This happens because the > redirection occurs before the head program is started. The > redirection truncates the file if it exist, so when the head is reading a file it is already empty.

Serge
  • 8,371
  • 2
  • 23
  • 28
  • Interesting. Do you have any detail on *why* it works this way? – cantlin Feb 19 '13 at 17:13
  • 3
    well, first bash (or the shell you are using) opens/creates the files it will use for redirection. Then it replaces the currently used file descriptors for stdin, stdout and stderr with the file descriptors it created for redirection as necessary. Then it executes the `fork` and `exec` system calls to start a new process thus the started process has the standard files redirected. Then bash restores its original file descriptors for itself. This is roughly what happens. – Serge Feb 19 '13 at 17:19
  • `head`, `sed` etc. are generally *inline editors* – Mateusz Jagiełło Feb 19 '13 at 18:19
  • 2
    Instead of redirecting the output of `head` to the file, you could pipe it to `tee` as such: `head -n3 foo.txt | tee foo.txt`. `tee` won't write to the file until it receives the data from `head` via the pipe. –  Feb 19 '13 at 21:02
  • @EvanTeitelman, ? Is `tee` documented to only open the output file *after* it has received input? – Aaron McDaid Jul 05 '16 at 18:15