Veja pergunta duplicada no serverfault:
A versão do pipe precisa de muito mais arquivos temporários. Você pode inspecionar isso rapidamente com o utilitário strace .
A versão do pipe usa um número explosivo rápido de arquivos temporários:
for i in {1..200000} ; do echo $i ; done |strace sort -n |& grep -e 'open.*/tmp/'
open("/tmp/sortb9Mhqd", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
open("/tmp/sortqKOVvG", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
open("/tmp/sortb9Mhqd", O_RDONLY) = 3
open("/tmp/sortqKOVvG", O_RDONLY) = 4
A versão do arquivo não usa arquivos temporários para o mesmo conjunto de dados. Para conjuntos de dados maiores, usa arquivos temporários muito menores.
for i in {1..200000} ; do echo $i ; done >/tmp/TESTDATA ; strace sort -n /TMP/TESTDATA |& grep -e 'open.*/tmp/'