32

UNIX philosophy says: do one thing and do it well. Make programs that handle text, because that is a universal interface.

The sort command, at least GNU sort, has an -o option to output to a file instead of stdout. Why is, say, sort foobar -o whatever useful when I could just sort foobar > whatever?

strugee
  • 14,951

2 Answers2

47

It is not just GNU sort that has it. BSD sort has it too. And as to why?
(I thought it was a good question too...)

From the man page: "The argument given is the name of an output file to be used instead of the standard output. This file can be the same as one of the input files."

You can't go to the same file with redirection, the output redirection wipes the file.

To further clarify, if I wanted to sort a file and put the sorted results in the same place I might think to try sort < foo > foo. Except the output redirection truncates the file foo in preparation to receive the output. And then there is nothing to sort. Without "-o" the way to do it would be sort < foo > bar ; mv bar foo. I assume the -o option does something similar without making you have to worry about it.

Timo
  • 6,332
kurtm
  • 7,055
  • 12
    You can also sudo sort -o /some/place that your non-privleged user doesn't have permission to write to. – bahamat Oct 06 '13 at 07:14
  • 8
    And to help avoid confusion with bahamat's comment: He is not saying that they can sort a file they don't have permissions for. I/O redirection works... poorly with sudo. Since the redirection takes place in your shell (sudo is just a command it is going to run), using redirection with a command via sudo is annoying. (I was initially confused as to what bahamat was saying, so figured others might be confused too). – kurtm Oct 06 '13 at 16:56
  • 4
    Just to play devil's advocate, there are actually alternatives to both the "input file is same as output file" problem and "privileged redirection" problem, and both alternatives are more in the spirit of "do one thing well". For "input = output", there is sponge (part of moreutils). For privileged redirection there is piping to | sudo tee, which also has the benefit of limiting privilege escalation to a single simple program, tee. – jw013 Oct 10 '13 at 17:58
  • Good points. Although the -o option to sort existed long before sponge did. It is at least as old as 4.4-lite2 (which is where the history starts in OpenBSD CVS). And for a case where you are operating on a non-privileged file and writing to a privileged area, | sudo tee works great, but for the majority of the time, you are wanting the whole thing to be privileged, and sudo trips you up. And sudo grep file | sudo tee is silly. – kurtm Oct 10 '13 at 19:59
  • 1
    sort needs to read the whole input before it can start outputting anything, that's why it can safely overwrite its input. It may store the data in memory or in temporary files before starting to output. – Stéphane Chazelas Oct 30 '13 at 12:53
12

The '-o' option was already in the the sort of the Sixth Edition of Unix

However I agree with you that it is not within the Unix philosophy. uniq did not have that option (and sort did not have a -u then).

On my PDP-11 I used a small program that would take one parameter:

renac whatever

If whatever already existed, it would write everything from stdin to a temporary file, that was only renamed to whatever after the stdin input dried up. That way you could pipe the output of any command into renac instead of redirecting to the filename without a chance of overwriting the input. Solving the overwriting problem in that way is IMHO more conform to the Unix philosophy.

Some later additions to the program were: not overwriting the output file if nothing had arrived on stdin (e.g. a result of mistyping part of the commandline), and allowing an option to append stdin to the named file.

This was one of the first (if not the first) real C programs that I made (for my job I mostly developed in Pascal on that system).

Anthon
  • 79,293
  • If I understood well, apt flavored GNU/Linux people can have a rewritten version of the functionality renac provided, with a program called sponge (from man: soak up standard input and write to a file), packagemoreutils`. – 41754 Oct 06 '13 at 09:12
  • @uprego. I just looked a the source of sponge.c and it seems to have a lot of code overhead because of the sponging (stdin -> stdout) functionality. – Anthon Oct 06 '13 at 10:45
  • @uprego neither sponge nor moreutils were actually created by GNU. – jw013 Oct 10 '13 at 18:05
  • I have not intended to assert that. – 41754 Oct 11 '13 at 10:04