News for hackers. Stuff that matters.
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.