Score:0

Send STDERR to console and file, STDOUT to file only

kr flag

I have some script with STDOUT and STDERR output. By default, both STDOUT and STDERR goes to console:

./script.sh

I can redirect STDOUT to file, leaving STDERR output in console:

./script.sh > log.txt

I can redirect both STDOUT + STDERR to same file with no output in console:

./script.sh > log.txt 2>&1

I can have both STDOUT and STDERR in console and logfile simultaneously:

./script.sh 2>&1 | tee -a log.txt

I don't want to see STDOUT, but I want to see STDERR, and I have to save everything in logfile. How could I have STDERR in console + logfile, while STDOUT in logfile only? Something like (pseudo-code, doesn't work):

./script.sh > log.txt 2 > /dev/tty | tee -a log.txt
Romeo Ninov avatar
in flag
Maybe something like will work: `./script.sh > log.txt | tee -a log.txt`
jp flag
@RomeoNinov: With that, the `> log.txt` would send the STDOUT to the file, STDERR left to STDERR. There's nothing left for the `tee` to handle. Therefore, it appends nothing to the file. You could confirm that easily with `./script.sh > log.txt | tee -a log2.txt`, which leaves the `log2.txt` empty.
Romeo Ninov avatar
in flag
@EsaJokinen, STDERR by default go to console. But to be sure the command can be corrected on this way: `./script.sh 2>&1 > log.txt | tee -a log.txt`. This way STDERR will go to STDOUT, STDOUT will go to file w/o STDERR.
jp flag
You would still need to use `>>` instead of `>`. With your current suggestion, if anything comes from STDOUT after something was already appended from STDERR, it would overwrite the file. That's why you absolutely need to append both streams, as explained in my answer. Even then, the order of the rows gets scrambled, because `tee` is separated & slower than `>>`.
Romeo Ninov avatar
in flag
@EsaJokinen, subshell + `tee` will be also slower than `>>` About need of `>>` maybe.
Score:4
jp flag

You would have to append both STDERR & STDOUT to the file. Otherwise the other of the streams would write over the other.

./script.sh >> log.txt 2> >(tee -a log.txt >&2)

Where:

  1. >> log.txt appends STDOUT to log.txt.
  2. 2> > sends the STDERR to to be processed by (tee -a log.txt >&2).
  3. tee -a log.txt splits that to the file log.txt in append (-a) mode and to >&2.
  4. As the STDERR was temporarily sent to STDOUT, the >&2 puts it back to STDERR.

Considerations

Because of the appending, if you run this twice, you would have the output twice in the file – which I suppose is the goal, given it is a log file. If you would like to have only the latest run in the log file, you would have to empty it first, e.g.,

> log.txt && ./script.sh >> log.txt 2> >(tee -a log.txt >&2)

The lines would not appear in chronological order, as >> works a bit faster tee -a. Because the latter has to fork another process, the output from STDERR would come to the file with a delay. If the correct order is critical, you cannot use this solution.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.