0

tee shows the stdout in terminal, I don't want it to do that but cant find an option

          || visible in terminal ||   visible in file   || existing
  Syntax  ||  StdOut  |  StdErr  ||  StdOut  |  StdErr  ||   file   
==========++==========+==========++==========+==========++===========
    >     ||    no    |   yes    ||   yes    |    no    || overwrite
    >>    ||    no    |   yes    ||   yes    |    no    ||  append
          ||          |          ||          |          ||
   2>     ||   yes    |    no    ||    no    |   yes    || overwrite
   2>>    ||   yes    |    no    ||    no    |   yes    ||  append
          ||          |          ||          |          ||
   &>     ||    no    |    no    ||   yes    |   yes    || overwrite
   &>>    ||    no    |    no    ||   yes    |   yes    ||  append
          ||          |          ||          |          ||
 | tee    ||   yes    |   yes    ||   yes    |    no    || overwrite
 | tee -a ||   yes    |   yes    ||   yes    |    no    ||  append
          ||          |          ||          |          ||
 n.e. (*) ||   yes    |   yes    ||    no    |   yes    || overwrite
 n.e. (*) ||   yes    |   yes    ||    no    |   yes    ||  append
          ||          |          ||          |          ||
|& tee    ||   yes    |   yes    ||   yes    |   yes    || overwrite
|& tee -a ||   yes    |   yes    ||   yes    |   yes    ||  append
Anon
  • 1
  • AFAIK the tee command doesn't have such an option - but you can simply redirect stdout to /dev/null (> /dev/null) if you don't want it to be displayed in the terminal – steeldriver Oct 28 '20 at 00:41
  • 2
    Why use tee at all? Doesn't standard > redirection do what you want? – Stephen Harris Oct 28 '20 at 01:00

1 Answers1

0

[Please edit your question; the title makes no sense, as that could be done with the simple > file redirection from the first row]

The missing rows could be done in bash with the 2> >(...) and > >(...) redirection + process substitution combinations.

E.g. for the most useful case (see full table at the end):

# both stderr+stdout to the tty, only stderr to the file
$ ls -d /etc /etx 2> >(tee file)
/etc
ls: cannot access '/etx': No such file or directory

$ cat file ls: cannot access '/etx': No such file or directory

Notice though that > >(...) tends to be tricky and buggy. Even when working fine, the stdout and stderr may come mixed up, or after the prompt:

bash$ sh -c 'sleep .1; ls -d /etc /etx' 2> >(tee errors)
ls: cannot access '/etx'/etc
: No such file or directory

bash$ ls -d /etc /etx 2> >(sleep .1; tee errors) /etc bash$ ls: cannot access '/etx': No such file or directory


Portably, it could be done by swapping the stdout and stderr with 3>&2 2>&1 >&3 3>&-:

$ ls -d /etc /etx 3>&1 >&2 2>&3 3>&- | cat | tee file
ls: cannot access '/etx': No such file or directory
/etc

$ cat file ls: cannot access '/etx': No such file or directory

Note: the "useless" cat is needed in order to dodge around tee's input buffering; stdbuf -i0 tee file should work too. Having the different outputs mixed up will always be a problem when you have multiple processes writing to the same place, which afaik cannot be fixed without intercepting the actual fprintf and similar calls within the application itself.


Tables

The appending forms were omitted; you can easily get them by replacing tee file with tee -a file and >file with >>file. The ... tee /dev/fd/3 ... 3 >&1 or 3>&2 ... commands could be simplified to tee /dev/tty if they're only intended to be run from an interactive terminal.

bash

TERMINAL      FILE
OUT  ERR    OUT  ERR
yes  yes    yes  yes     cmd |& tee file
yes  yes    yes   no     cmd | tee file
yes  yes     no  yes     cmd 2> >(tee file)
yes  yes     no   no     cmd
yes   no    yes  yes     (cmd | tee /dev/fd/3) 3>&1 &>file
yes   no    yes   no     cmd 2>/dev/null | tee file
yes   no     no  yes     cmd 2>file
yes   no     no   no     cmd 2>/dev/null
 no  yes    yes  yes     (cmd 2> >(tee /dev/fd/3)) 3>&2 &>file
 no  yes    yes   no     cmd >file
 no  yes     no  yes     cmd 2> >(tee file) >/dev/null
 no  yes     no   no     cmd >/dev/null
 no   no    yes  yes     cmd &>file
 no   no    yes   no     cmd >file 2>/dev/null
 no   no     no  yes     cmd >/dev/null 2>file
 no   no     no   no     cmd &>/dev/null

Standard /bin/sh

TERMINAL      FILE
OUT  ERR    OUT  ERR
yes  yes    yes  yes     cmd 2>&1 | tee file
yes  yes    yes   no     cmd | tee file
yes  yes     no  yes     cmd 3>&2 2>&1 >&3 3>&- | tee file
yes  yes     no   no     cmd
yes   no    yes  yes     (cmd | tee /dev/fd/3) 3>&1 >file 2>&1
yes   no    yes   no     cmd 2>/dev/null | tee file
yes   no     no  yes     cmd 2>file
yes   no     no   no     cmd 2>/dev/null
 no  yes    yes  yes     (cmd 4>&2 2>&1 >&4 4>&- | tee /dev/fd/3) 3>&1 >file 2>&1
 no  yes    yes   no     cmd >file
 no  yes     no  yes     cmd 2>&1 >/dev/null | tee file
 no  yes     no   no     cmd >/dev/null
 no   no    yes  yes     cmd >file 2>&1
 no   no    yes   no     cmd >file 2>/dev/null
 no   no     no  yes     cmd >/dev/null 2>file
 no   no     no   no     cmd >/dev/null 2>&1