0

I would like to print something (e.g. the current date) to both STDOUT and STDERR, without redirecting any of them.

I tried:

date 1>&2

But I think this just redirects stdout to stderr, which is not what I want. I want to print to BOTH, without merging them in the same file.

I believe tee could help, but I'm not sure how to use it.

1

2 Answers 2

1

If I understand what you want, tee command is the solution:

your_command 2>&1 | tee /dev/stderr

The output error of your command (ie. date) is redirected to the standard output (with 2>&1). The result is doubled with tee command.

  • One to standard output;
  • The second to the file in parameter: /dev/stderr

Then, the result with date command is:

> date 2>&1 | tee /dev/stderr
Sun Dec 11 16:33:35 CET 2022
Sun Dec 11 16:33:35 CET 2022

So, you could redirect with > / >> and 2> / 2>> to any files you want:

> date 2>&1 | tee /dev/stderr >file1 2>file2
> cat file1
Sun Dec 11 16:40:59 CET 2022
> cat file2
Sun Dec 11 16:40:59 CET 2022

If an error occurs, with a bad command like datex:

> datex 2>&1 | tee /dev/stderr >file1 2>file2
> cat file1
bash: datex: command not found...
> cat file2
bash: datex: command not found...
4
  • Thanks. But isn't this the same as date | tee /dev/stderr ? It seems simpler!
    – a06e
    Commented Dec 11, 2022 at 16:20
  • 1
    slight variation: date | tee >(cat >&2) Commented Dec 11, 2022 at 17:02
  • @glennjackman why not tee >(cat 1>&2) ? (from stackoverflow.com/a/20553986/855050) The 1 is not needed?
    – a06e
    Commented Dec 11, 2022 at 20:35
  • @becko date | tee /dev/stderr do not redirect the command (date) error output to the pipe Commented Dec 11, 2022 at 21:14
1

In zsh, that's just

date >&1 >&2

In zsh, unless the multios option is disabled, when a fd is redirected more than once for output¹, zsh redirects it instead to a pipe and reads the data from the other end to dispatch it to the targets in a tee-like fashion.

In other shells, you can do the teeing with perl for instance:

date | perl -ne 'BEGIN{$/=\8192} print; print STDERR'

On systems other than Cygwin and Linux-based ones, you can do:

date | tee /dev/stderr

On Linux/Cygwin that should be avoided as there, opening /dev/stderr tries to reopen the file that /dev/stderr points to anew, and writing to the resulting file descriptor is not the same as writing to stderr. It should be functionally equivalent though when stderr is open on a pipe or tty device as it often is.


¹ and beware that includes pipes as in cmd >&2 | cmd2 which can be a bit surprising.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .