检索 tee 命令的底层文件

Retrieve underlying file of tee command

参考资料

此处将讨论的内容的完整代码: https://github.com/djon2003/com.cyberinternauts.linux.backup

activateLogs 解决了 如何登录到文件和屏幕的问题

限制

最后一个问题的小提醒:这个脚本是在有限的环境中执行的,在 QNAP (NAS) 上。

背景

我有一个激活日志记录的功能,它现在具有三种模式:屏幕、磁盘、两者。在一些帮助下(来自上面 link 的问题),我实现了 BOTH 选项。 DISK & BOTH 使用编号为 3 的文件描述符。第一个指向文件,第二个指向标准输出。

在我的脚本退出时(使用陷阱),它会检测是否有记录的错误并通过电子邮件发送它们。

代码

function sendErrorMailOnExit()
{
    ## If errors happened, then send email
    local isFileDescriptor3Exist=$(command 2>/dev/null >&3 && echo "Y")
    if [ "$isFileDescriptor3Exist" = "Y" ]; then
        local logFile=$(readlink /proc/self/fd/3 | sed s/.log$/.err/)
        local logFileSize=$(stat -c %s "$logFile")
        if [ $logFileSize -gt 0 ]; then
            addLog "N" "Sending error email"
            local logFileName=$(basename "$logFile")
            local logFileContent=$(cat "$logFile")
            sendMail "Y" "QNAP - Backup error" "Error happened on backup. See log file $logFileName\n\nLog error file content:\n$logFileContent"
        fi
    fi
}
trap sendErrorMailOnExit EXIT

问题

如您所见,这很有效,因为文件描述符 #3 正在使用一个文件。但是现在,使用 BOTH 选项,文件描述符 #3 指向标准输出并且文件是通过 tee 写入的。因此我的问题是,如何获取 tee.

文件的位置

为什么不只使用来自我的函数的变量 activateLogs 你会说吗?因为,此函数会重新启动脚本,以便能够获取调用该函数之前未捕获的所有日志。因此,为什么要使用此方法来检索错误文件位置。

可能的解决方案,但不是最好的(我希望)

  1. 一种方法是通过脚本传递文件位置 参数,但如果可以避免的话,我宁愿不这样做。
  2. 另一个方法是创建一个始终指向该文件的“假”文件描述符 #4(可能是我迄今为止最好的解决方案)。

有人知道吗?

我最终选择创建一个“假”文件描述符 #4,它除了指向当前日志文件外什么都没有。