News for hackers. Stuff that matters.
Re:"Rules" that terminal programs follow by matheusmoreira on Thursday December 12, 2024 @02:37PM (#42402559)
> programs should print “regular” output to stdout and errors to stderr

This is really important. I'd like to expand on this.

Standard output is for the data the program was asked to produce, no more and no less. If user asked for some JSON data, standard output should contain that exact JSON object and absolutely nothing else.

Standard "error" is actually a misnomer. It should have been called the standard user stream. Anything meant for the user to read on the terminal is supposed to go there. Error messages are of course included in that set but so are status messages and verbose output.

This ensures the output of programs can be piped into other programs seamlessly. Non-output data still gets sent to the terminal or redirected somewhere else.

Would have been great if programs were able to easily create new terminal-connected file descriptors for specific purposes. They could document those numbers in their manuals just like they document exit codes. Then users would get "ports" for every output. Could cut down on parsing significantly.

For compatibility, they could all redirect to either standard output or standard error by default... I think I'm gonna experiment with this a bit.

Re:"Rules" that terminal programs follow by packetlost on Thursday December 12, 2024 @02:42PM (#42402601)
I'm not sure I like the "standard user stream" name, but I otherewise agree with everything here.
Re:"Rules" that terminal programs follow by paulddraper on Thursday December 12, 2024 @04:07PM (#42403336)
I'd name it "standard log."

That's what it is....a log of errors, warnings, information messages, whatever to complement the primary output.

Re:"Rules" that terminal programs follow by matheusmoreira on Thursday December 12, 2024 @02:47PM (#42402657)
Yeah, naming is hard. If there is a better word for "non-output", I don't know it.
Re:"Rules" that terminal programs follow by packetlost on Thursday December 12, 2024 @02:48PM (#42402663)
I would maybe call it stdlog or stdinfo vs stderr, but yeah naming things is hard.
Re:"Rules" that terminal programs follow by ryandrake on Thursday December 12, 2024 @03:33PM (#42403066)
C++ has std::clog[1], but it's basically cerr, and the OS still only knows about stdin, stdout, and stderr.

1: https://cplusplus.com/reference/iostream/clog/

Re:"Rules" that terminal programs follow by matheusmoreira on Thursday December 12, 2024 @02:52PM (#42402709)
I think stdinfo would exclude error messages from the definition, just like stderr excludes info messages.

I really like stdlog. Standard log stream is a pretty awesome name. Short and terse, the word "log" doesn't even need abbreviation and it's correct since it's a superset of error and info streams and also generic enough to cover other unforeseen categories.

I'll use it from now on!

Re:"Rules" that terminal programs follow by packetlost on Thursday December 12, 2024 @03:55PM (#42403230)
The idea for info is that it's informational, which is always the case regardless of whether it's printing error messages due to a failure or informational messages because the user specified a `-v` flag or whatever. Whether the command failed or not is communicated via the exit code. That being said, I do prefer stdlog for the reasons: it communicates the intent and usage as unambiguously and tersely as possible.
Re:"Rules" that terminal programs follow by matheusmoreira on Thursday December 12, 2024 @04:11PM (#42403376)
> because the user specified a `-v` flag or whatever

The way I see it is the version information and help text belong on standard output if the user passes --version and --help since that's what the user explicitly asked for. When the command is invoked incorrectly, the help text should go to standard error while standard output should be empty.

I agree about the exit code. People like to parse error messages and that's always wrong. Everything should be done via exit codes instead.

Re:"Rules" that terminal programs follow by packetlost on Thursday December 12, 2024 @04:56PM (#42403826)
The `-v` was in reference to the common convention of one or more `v` flags increasing the verbosity of logging.
Re:"Rules" that terminal programs follow by saghm on Thursday December 12, 2024 @04:57PM (#42403829)
What about "debug"? I think the important part about stderr is that it's "meta" info about how the program is running (or ran) rather than what the program is intended to produce as output. This seems pretty similar to what often is referred to as the "debug" level of logging (which includes lower levels of logging like warnings and errors).
Re:"Rules" that terminal programs follow by lionkor on Thursday December 12, 2024 @03:02PM (#42402824)
Unless your app doesn't generate output,then grepping the output will not work if it's stderr and it will be confusing
Re:"Rules" that terminal programs follow by bombcar on Thursday December 12, 2024 @03:23PM (#42402989)
You can learn the 2>&1 thing, but it would be nice if there was a feature of one of the greps to "slurp up" the error output.

Of course, the real problem is there's no standard, the standards that do exist are ignored, and each new command-line tool generates a new standard.

Re:"Rules" that terminal programs follow by sudobash1 on Thursday December 12, 2024 @03:45PM (#42403156)
It generally isn't possible for grep to "slurp up" the error output because stderr does not get passed through pipes (by default). This is shell behavior and grep cannot do anything about it.

As a side note, some shells have started implementing a shorthand for `foo 2>&1 | grep` which is `foo |& grep`.

Re:"Rules" that terminal programs follow by ElevenLathe on Thursday December 12, 2024 @04:06PM (#42403330)
Probably you could do a hack like finding the program at the other end of the pipe and looking at its open file descriptors, but lots of corner cases to consider.
Re:"Rules" that terminal programs follow by kelnos on Thursday December 12, 2024 @06:06PM (#42404341)
Right, the problem is that apparently shells haven't seen user need for selectively redirecting one or the other. Like I might want to see foo's stdout on the terminal, but pipe stderr (and only stderr) to grep, perhaps so I only see some specific error messages that I care about. `2>&1` will send stderr to stdout, and then the pipe will send everything to grep (and I believe `|&` does the same).

(To be fair, that does seem like a pretty rare use case.)

Re:"Rules" that terminal programs follow by sudobash1 on Thursday December 12, 2024 @07:07PM (#42404733)
Actually, you can. If you run:

    foo 2>&1 >&- | grep ...
then you will grep only the stderr. The stdout will be discarded.

Alternatively, if you only want to grep to see the stderr, but you still want to see stdout, you can swap stderr and stdout like this:

    foo 3>&2 2>&1 1>&3 | grep ...
And in many shells, you can easily split the stdout and stderr into two separate pipelines like this:

    foo > >(grep stdout) 2> >(grep stderr)
Re:"Rules" that terminal programs follow by wahern on Thursday December 12, 2024 @07:24PM (#42404816)
> Like I might want to see foo's stdout on the terminal, but pipe stderr (and only stderr) to grep, perhaps so I only see some specific error messages that I care about

You mean this:

`foo 3>&1 1>&2 2>&3`

The above swaps stdout and stderr, saving + restoring the original stdout through descriptor 3. Shell redirection expressions map directly to dup2 syscalls, except the operands are reversed: 3>&1 is dup2(1, 3). Pipes map fairly simply to fork + exec. At its core the shell is a rather thin wrapper around the core Unix syscalls fork, exec, dup2, open, and close. If you look at the original shell implementation, the command parser more-or-less executes these syscalls as it goes along, left to right.

Re:"Rules" that terminal programs follow by matheusmoreira on Thursday December 12, 2024 @04:08PM (#42403341)
How can you grep output if there's no output?

Can you provide a concrete example of such an application?

Re:"Rules" that terminal programs follow by d3VwsX on Friday December 13, 2024 @09:16AM (#42408577)
Some applications print usage information (e.g. with --help flag) to stderr. That is a bit annoying when there is a lot of output and I just want to grep for some flag, since the first attempt will fail and then I have to try again after adding 2>&1.
Re:"Rules" that terminal programs follow by quectophoton on Friday December 13, 2024 @11:57AM (#42410204)
Then there's `ssh-keyscan`, printing the "real" output to stdout, but also printing "comments" to stderr.

Nothing wrong with that, but it was a bit confusing the first time I saw that behavior.

Re:"Rules" that terminal programs follow by matheusmoreira on Friday December 13, 2024 @06:14PM (#42413192)
If I pass the --help flag, I'm explicitly asking the program to print the help text. In this case it's appropriate for the help text to be written to standard output since the help text is the output.

If the user passes invalid options and inputs, then the program should produce no output and any error or help messages should be written to the error stream. It's important that these messages end up on the terminal when one gets the command invocation wrong while trying to pipe data into another program. If they're written to standard output, the program on the other end of the pipe will slurp all the error messages up and try to parse them as though they were valid inputs.

Re:"Rules" that terminal programs follow by quectophoton on Friday December 13, 2024 @12:07PM (#42410294)
I think what they meant was something like:

> Unless your app doesn't generate [stdout] output,then grepping the [visible] output will not work if it's stderr and it will be confusing

With the first "output" meaning "specifically stdout", and the second meaning "what you see on the terminal".

As in, you run a command, see it printed a lot of stuff, so then you do it again but piping it to `grep` or `less`, and realize none of that output was actually going to stdout.

Re:"Rules" that terminal programs follow by matheusmoreira on Friday December 13, 2024 @06:25PM (#42413294)
I see what you mean. My logic only really applies to the simpler programs which exclusively use the standard file descriptors. It gets fuzzier when the output of a program is an actual file somewhere.

The output of a package manager is the packages. The text it writes to the terminal is not part of the output, it's just the program's log. I haven't thought about what's appropriate in this situation. By unix standards package managers shouldn't even be printing anything to begin with.

Re:"Rules" that terminal programs follow by AndrewDucker on Thursday December 12, 2024 @04:51PM (#42403787)
This is definitely one of the things that PowerShell got right. 6 different streams, each of which can be intercepted separately and configured differently.

https://learn.microsoft.com/en-us/powershell/module/microsof...

Re:"Rules" that terminal programs follow by immibis on Thursday December 12, 2024 @05:41PM (#42404171)
I don't think that 6 different streams that will always go to the same place but some of them are usually turned off are very useful. Standard-error/user is useful because it goes to a different place. Levels would be better suited to a simple global variable, or a level associated with each printed line. The chance that someone redirects errors to error.log is reasonable, but the chance that someone redirects errors to error.log and warnings to warning.log and debug to debug.log and verbose to verbose.log is pretty low.
Re:"Rules" that terminal programs follow by AndrewDucker on Friday December 13, 2024 @04:24AM (#42407170)
I turn on Verbose logging sometimes, to get more info.

Error logging can be set to either spit out the error and continue, or to stop processing, which is very useful.

Warning and error messages come out in their own colours automatically, which is nice.

And sure, you can just have them all come out to the same place. But having the options to configure them is very handy.

Re:"Rules" that terminal programs follow by immibis on Friday December 13, 2024 @05:14AM (#42407379)
None of this is related to them being separate streams instead of metadata in one stream
Re:"Rules" that terminal programs follow by matheusmoreira on Thursday December 12, 2024 @05:40PM (#42404164)
There's a lot of good ideas in power shell. I like how they broke up the log stream into separate streams by severity. It still seems arbitrary and insufficiently general though. Why severity and not some other criteria?

What if programs could define any number of output streams? By default they could all coalesce into the terminal but other programs could connect to each one separately if they needed. Like an audio mixer of sorts: by default you get the mixed audio but there are ways to access each individual voice if needed.

Re:"Rules" that terminal programs follow by MatejKafka on Friday December 13, 2024 @07:05AM (#42407830)
Also related to the article, PowerShell has PSReadLine, which implements a pretty reasonable text editor, including selection, copy/paste, classic keybindings such as Home/End/Ctrl-arrows, sane multiline command editing, semantic autocomplete and custom actions that can operate on input AST.

Once you get used to having all that, going back to other shells is pretty hard.