4

是否有一个文件名可以分配给一个变量(即不是一个神奇的内置 shell 令牌,比如&1),让我重定向到stdout

我最终想要做的是在 cron 脚本中运行这样的东西:

LOG=/tmp/some_file
...
some_command 2>&1 >> $LOG
echo "blah" >> $LOG
...

/dev/null方便的是,当我确定没有任何事情会失败(或者,至少没有我关心的事情!)时,我可以通过重定向来关闭日志噪音,而无需重写整个脚本。是的,关闭日志记录并不是最佳实践——但是一旦这个脚本工作,就没有多少可以想象的错误了,并且不希望使用没有人想要读取的兆字节日志信息来破坏磁盘。
如果 5 年后出现意外故障,仍然可以通过拨动开关再次打开日志记录。

另一方面,在编写和调试脚本时,需要从 shell 手动调用它,如果它可以将输出转储到控制台,那就太好了。这样我就不需要tail手动记录日志文件。

换句话说,我正在寻找的是/proc/self/fd/0我可以分配给 bash-talk的东西LOG。碰巧,/proc/self/fd/0在我的 Linux 机器上工作得很好,但我想知道 bash 中是否还没有内置这样的东西(这通常是可取的)。

4

4 回答 4

6

基本解决方案:

#!/bin/bash
LOG=/dev/null

# uncomment next line for debugging (logging)
# LOG=/tmp/some_file

{
  some_command
  echo "blah"
} | tee 1>$LOG 2>&1

更进化:

#!/bin/bash

ENABLE_LOG=0       # 1 to log standard & error outputs
LOG=/tmp/some_file

{
  some_command
  echo "blah"
} | if (( $ENABLE_LOG ))
then
  tee 1>$LOG 2>&1
fi

DevSolar 的想法更优雅的解决方案:

#!/bin/bash

# uncomment next line for debugging (logging)
# exec 1> >(tee /tmp/some_file)  2>&1

some_command
echo "blah"
于 2013-07-31T11:44:18.270 回答
3

感谢 olibre 和 suvayu 的精彩提示,我想出了这个(为了记录,我现在正在使用的版本):

# log to file
# exec 1>> /tmp/logfile 2>&1

# be quiet
# exec 1> /dev/null 2>&1

# dump to console
exec 2>&1

只需要取消注释这三个中的一个,这取决于所需的内容,并且再也不用担心其他任何事情。这要么将所有后续输出记录到文件控制台,要么根本不记录。
没有重复的输出,每个命令的工作方式都相同(没有明确的重定向),没有奇怪的东西,并且尽可能简单。

于 2013-07-31T12:54:15.750 回答
2

如果我清楚地理解了您的要求,那么以下应该做您想要的

exec 2>&1
exec >> $LOG

所有后续命令的 stdout 和 stderr 都将附加到文件$LOG中。

于 2013-07-31T11:29:14.950 回答
1

利用/dev/stdout

这是另一个提到此解决方案的 SO 答案:Difference between stdout and /dev/stdout

于 2020-06-19T20:27:34.120 回答