如何将标准输出重定向到文件而不在终端中显示内容?

如何将标准输出重定向到文件而不在终端中显示内容?

tee在终端中显示标准输出,我不希望它这样做,但找不到选项

          || 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

答案1

[请编辑您的问题;标题没有意义,因为这可以通过> file从第一行进行简单的重定向来完成]

缺失的行可以在巴什与重定向+进程替换组合2> >(...)> >(...)

例如,对于最有用的情况(请参阅最后的完整表格):

# 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

请注意,这> >(...)往往很棘手且有问题。即使工作正常,stdout 和 stderr 也可能会混淆,或者在提示后:

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

可移植的是,可以通过将 stdout 和 stderr 交换为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

注意:需要“无用”的猫来躲避 tee 的输入缓冲;stdbuf -i0 tee file也应该有效。将不同的输出混合在一起将会总是当您有多个进程写入同一位置时,这是一个问题,据我所知,如果不拦截fprintf应用程序本身内的实际和类似调用,就无法修复该问题。


表格

省略了附加表格;您可以通过替换tee filetee -a file>file轻松获得它们>>file。如果这些命令仅打算从交互式终端运行,则... tee /dev/fd/3 ... 3 >&1 or 3>&2 ...可以将它们简化。tee /dev/tty

巴什

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

标准/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

相关内容