sorting a file using the sort command and overwrite it

i was trying to sort a text file and replace the sorted file with the original one, so i set the file to be also the output of the sort command too, but when i do that it clears the file contents and the file becomes empty, why? i can use another file to solve this problem but it doesn't feel nice :D, ( and i'm using Lubuntu. )

faav@faav-XPS-L501X:~$ cat test
A
C
B
faav@faav-XPS-L501X:~$ ls -l test
-rw-rw-r-- 1 faav faav 6 Apr 14 00:28 test
faav@faav-XPS-L501X:~$ sort test > test
faav@faav-XPS-L501X:~$ cat test
faav@faav-XPS-L501X:~$ ls -l test
-rw-rw-r-- 1 faav faav 0 Apr 14 00:28 test

Solution 1:

Use the -o option of sort instead of using redirection operator, this will edit the file in place.

From man sort:

-o, --output=FILE
              write result to FILE instead of standard output

Here is a test:

$ cat test.txt 
A
C
B

$ sort test.txt 
A
B
C

$ sort test.txt -o test.txt

$ cat test.txt 
A
B
C

Solution 2:

This happens because the input / output file is truncated before its content is actually read, so sort ends up reading an already empty file.

In general (i.e. while redirecting the output of a command to its input file, since this issue doesn't only happen with sort), you can execute the required command within a subshell and store its output to a variable, then flush the content of the variable to the file (e.g. with echo), this way delaying the truncation of the input / output file to a point where the input file has been read already:

tmp=$(sort test) && echo "$tmp" >  test

Also note that this is not very efficient for large files, and that the && operator has been chosen in place of ; to avoid the truncation of the input / output file in case of a failure of the first command.