如何将 shell 脚本 stdout/stderr 打印到 file/s 和控制台

How to print shell script stdout/stderr to file/s and console

在 bash 脚本中,我使用以下语法来打印从脚本到文件的所有内容 - $file$sec_file

我们正在 运行在我们的 Linux rhel 服务器 - 版本 7.8

上安装脚本
exec > >(tee -a "$file" >>"$sec_file") 2>&1

所以在 bash 脚本完成后,我们在两个文件中得到 bash 脚本

中每一行的 stdout/stderr 的内容

现在我们还想将 stdout/stderr 打印到控制台,而不仅仅是文件

我会很感激任何建议

脚本示例:

# more  /tmp/script.bash

#!/bin/bash

file=/tmp/file.txt
sec_file=/tmp/sec_file.txt

exec > >(tee -a "$file" >>"$sec_file") 2>&1

echo "hello world , we are very happy to stay here "

示例如何 运行 脚本:

/tmp/script.bash

<--  no output from the script -->

# more /tmp/file.txt
hello world , we are very happy to stay here
# more /tmp/sec_file.txt
hello world , we are very happy to stay here

预期输出示例应如下所示

/tmp/script.bash
hello world , we are very happy to stay here

# more /tmp/file.txt
hello world , we are very happy to stay here
# more /tmp/sec_file.txt
hello world , we are very happy to stay here

我认为,最简单的方法是将多个文件作为参数添加到 tee,如下所示:

% python3 -c 'import sys; print("to stdout"); print("to stderr", file=sys.stderr)' 2>&1 | tee -a /tmp/file.txt /tmp/file_sec.txt
to stdout
to stderr
% cat /tmp/file.txt 
to stdout
to stderr
% cat /tmp/file_sec.txt 
to stdout
to stderr

那么您的脚本将如下所示:

#!/bin/bash

file=/tmp/file.txt
sec_file=/tmp/sec_file.txt

exec > >(tee -a "$file" "$sec_file") 2>&1

echo "hello world , we are very happy to stay here "

我建议只将控制台内容写入新的输出通道:

#!/bin/bash
file=file.txt
sec_file=sec_file.txt

exec 4>&1 > >(tee -a "$file" >>"$sec_file") 2>&1

echo "stdout"
echo "stderr" >&2
echo "to the console" >&4

输出:

me@pc:~/⟫ ./script.sh 
to the console
me@pc:~/⟫ cat file.txt 
stdout
stderr
me@pc:~/⟫ cat sec_file.txt 
stdout
stderr

如果你愿意,你可以这样做,甚至可以使用 >&5:

再次写入 stderr
exec 4>&1 5>&1 > >(tee -a "$file" >>"$sec_file") 2>&1
echo "stderr to console" >&5

编辑:将 &3 更改为 &4,因为 &3 有时用于标准输入。

但也许现在是重新考虑您正在做的事情并保留 &1 stdout 和 &2 stderr 并使用 &4&5 写入文件的时刻?

exec 4> >(tee -a "$file" >>"$sec_file") 5>&1

这确实需要您添加到文件中应该结束的所有行以预先添加 >&4 2>&5