如何在shell脚本中强制每个命令都运行`tee`?

4
我希望有一个脚本,可以将所有命令都记录在日志文件中,使用tee命令实现。
目前,我是这样运行脚本中的每个命令:
<command> | tee -a $LOGFILE

有没有一种方法可以强制shell脚本中的每个命令都通过管道传输到tee?我无法强制用户在运行脚本时添加合适的tee,并希望即使调用用户没有添加自己的日志记录调用,也能确保它正确记录日志。
4个回答

18

你可以在你的脚本中创建一个包装器:

#!/bin/bash
{
echo 'hello'
some_more_commands
echo 'goodbye'
} | tee -a /path/to/logfile

编辑:

这是另一种方法:

#!/bin/bash
exec > >(tee -a /path/to/logfile)
echo 'hello'
some_more_commands
echo 'goodbye'

我喜欢这个 - 没想过使用括号。 - warren
2
使用 exec > >(tee -a /path/to/logfile) 2>&1 将错误输出到文件中,以便在一个文件中记录所有发生的事情。 -a 是追加,但您也可以删除它以便每次都从头开始记录文件。 - god_is_love

2
为什么不暴露一个简单的包装器呢?
/path/to/yourOriginalScript.sh | tee -a $LOGFILE

您的用户不应该执行(也不知道)yourOriginalScript.sh


(您需要确保脚本在后台运行,并且用户无法访问或执行它。)

2
假设你的脚本没有使用--tee参数,那么你可以这样做(如果你使用了该参数,请将下面的--tee替换为你不使用的参数):
#!/bin/bash

if [ -z "$1" ] || [ "$1" != --tee ]; then
  $0 --tee "$@" | tee $LOGFILE
  exit $?
else
  shift
fi
# rest of script follows

这只是让脚本重新运行自己,使用特殊的参数--tee来防止无限递归,并将其输出导入到tee中。


也可以使用 exec 来避免额外的进程:if ...; then exec $0 --tee "$@"; else; shift; fi(不再需要退出)... - FooF

1
一些方法是创建一个名为“run_it”的运行脚本,让所有用户调用自己的脚本。
run_it my_script

所有的魔法都将在内部完成,例如可能看起来像这样:

LOG_DIR=/var/log/
$@ | tee -a  $LOG_DIR/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接