Shell, explained

Why sort file > file empties your file

sort names.txt > names.txt

The shell sets up the > redirection before sort starts, and > empties the file straight away. When sort then opens names.txt, there is nothing left to read, so it writes nothing back. The file ends up empty.

The file is emptied before sort reads it

Run for real, names.txt ends up 0 bytes long.

$

Tap a part of the command to find it below

$ sort names.txt

reads names.txt after > has emptied it

output → names.txt

>names.txtEMPTIED FIRST

> empties names.txt before sort starts, so sort reads an empty file

−Cy
−Ana
−Bo

now empty

Tap any part of the command to see what it does

The fix: write somewhere else, then move it

sort reads the untouched file, writes sorted.txt, and only if that worked does mv put it in place.

$

Tap a part of the command to find it below

$ sort names.txtEXIT 0

output → sorted.txt

>sorted.txtREPLACED
Ana
Bo
Cy
&&

exit 0: sort succeeded, so mv runs

$ mv sorted.txt names.txtOUTPUT

no output

Tap any part of the command to see what it does

Part by part

sort names.txt
Reads names.txt and prints its lines in order.
>
Opens the output file and empties it, before the command even starts.
names.txt
The same file sort was going to read: by then it is empty.

Common mistakes

The same trap through a pipe

cat names.txt | sort > names.txt usually fails the same way: every part of the pipeline is set up at once, and the file is often emptied before cat gets to read it.

Thinking >> is safe

>> does not empty the file, but it appends the sorted lines after the unsorted ones, so you end up with both.

Try it

$ sort -o names.txt names.txt

-o is safe: sort reads everything before it writes.

$ sort names.txt > sorted.txt && mv sorted.txt names.txt

Works with any command.

$ sort names.txt | sponge names.txt

sponge (from moreutils) soaks up all input before writing.

Questions

Why does sort -o work?

sort reads all of its input before it opens the output file, so with -o it never empties the file it still needs.

Does this happen with other commands?

Yes, with any command that reads a file you also redirect into with >: grep, sed, cut, awk… For sed, use sed -i to edit in place.

Can I get the data back?

Not from the shell: the file was truncated. Restore it from version control, a backup or your editor's history.

Terminaster

Ask about any command and get a picture like this one.

The Terminaster tutor draws these visuals for your own questions, then turns what you learned into spaced-repetition cards so it sticks.