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
reads names.txt after > has emptied it
output → names.txt
> empties names.txt before sort starts, so sort reads an empty file
now empty
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
output → sorted.txt
exit 0: sort succeeded, so mv runs
no output
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.txtWorks with any command.
$ sort names.txt | sponge names.txtsponge (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.
The ideas behind it
Redirection
Redirection is shell syntax that opens, closes, or duplicates file descriptors for a command before that command begins executing.
Pipelines
A pipeline connects the standard output of each command to the standard input of the next, allowing multiple processes to transform a byte stream concurrently.