Yes. And it makes perfect sense for it to be weird. To begin with, it was created by a very unpleasant person, who has no respect for tradition and for good engineering, and likes to offend people (Linus). Matter-of-fact, its design goal was the "principle of the most surprise": do everything in a fashion most backwards and unusual, deliberately the opposite of cvs. And it was created as a deliberate reaction to two unpleasant reactions Linus had with people (Andy T and Larry M). The name "git" is a deliberate insult to either Andy and Larry (that's their interpretation), or to himself (that's his excuse).Git is weird.
No. In some cases, Windows made really good design decisions. Those we should copy. But only those. For example, the "dir /?" auto paging should go. On the other hand, SMB/CIFS is a much better file sharing protocol than NFS. The attitude of "let's do the exact opposite of what has been done before", when used uncritically, leads to exactly the kind of disaster that git has become.and it is a general rule that good software should do the opposite of what Windows does.
Anyway, to the topic at hand. Here are the ways I like to do things:
- If the program runs successfully, stderr will have zero bytes of output. If the program fails, it will have error messages and helpful suggestions on stderr. This immediately implies that length(stderr) > 0 happens if and only if status != 0.
- stdout contains the output that can be processed by a downstream program. If the output is in a specific format (for example a table where every line has exactly 7 columns), every line on stdout will be in that format.
- This implies that it is quite possible for there to be output on both stdout (real results) and stderr, if the program fails after it started working.
- It also means that if you print a brief usage message (the one that explains what options exist), usually in reaction to a "-h" flag, it violates the rule about formatting above. The way I work around this is: if -h is given, it must be the only option, and the program will output a brief help message (usually explaining the options and parameters only), perhaps with a link to more extensive documentation, for example "See man elephant" or "See /usr/local/share/elephant/readme.txt" or "See http://localhost/elephant/readme.html".
- That brief usage message is also given (on stderr!) in case the parsing of command line options and parameters doesn't work.
- There is a significant difference between a brief help message (which you should get from "elephant -h"), a user manual (which is available as "man elephant"), and in-depth documentation (which might be in a readme file or web page). The extensive documentation will contain the brief help message and user manual as subparts, but it should also include things like extensive examples, usage patterns, theory of operations, and software design and debug / maintenance guides.
- Most command-line Unix programs are written as filters or generators: They may read information (on stdin by default, from files when necessary), and they send results to stdout. For those, there is no reason to support sending the output to a file, nor is there a need to redirect it to a pager. If the user wants to run the output through more, they're free to do so, and it is easy to do.
- Another reason to not automatically page the output is this: Today, we universally use virtual terminals; nobody use a Wyse or a VT100 any longer. That means that nearly all CLI users have a scroll bar. For an output of 100 or 200 lines, some users (including me) prefer to have the output simply show up on the screen, and instead of saying "elephant | more", I just scroll the window around. Forcing me to hit the space bar 20 times to get all the output just causes pain, for no gain.
- The exception to this rule is a whole other class of programs, namely those that process commands internally. The standard mail program or debugger is an example: You start them, and they give you a prompt. At that prompt you are not dealing with a shell, but with a built-in command parser (often built around readline). Here, the user doesn't have easy facilities available to run the output of a command through more (or grep or awk), so automatically paging the output (based on the $PAGER variable) is a good idea.
- On human-readable output, we can today assume that all terminals can handle ansi color/rendering escape sequences, and common Unicode characters. So it's perfectly fine to report a temperature as 69.2°F, or a measurement and regression accuracy as "54.7 ± 0.7 psi χ²ₙ=1.37", because I'm sure that degree, chi, plus minus and subscript n will be available on all terminals (including the console). Similarly, a diff tool can use red and green text to mark changed and identical sections, and boldface changed words. But if you do that, make sure to provide a command line switch to turn escape sequences and unicode off, for processing the output with downstream tools (such as awk) that don't like these. And to help users who are color-blind or neuro-diverse and don't like to deal with rendering.
- Changing output formats (including turning a pager on or off) depending on whether stdout goes to a terminal device or a pipe or a file is evil. It is an example of making decisions based on heuristics that are sometimes right, but often enough wrong. For example, whether I run "diff elephant hippo" or "diff elephant hippo | more" should not change whether the results are colorized or not. Too many programs violate that rule.