如何终止 Linux tee 命令而不终止它接收的应用程序

Phi*_*Bot 20 linux scripting kill pipe tee

我有一个 bash 脚本,只要 Linux 机器开机就可以运行。我按如下所示启动它:

( /mnt/apps/start.sh 2>&1 | tee /tmp/nginx/debug_log.log ) &
Run Code Online (Sandbox Code Playgroud)

启动后,我可以在ps输出中看到 tee 命令,如下所示:

$ ps | grep tee
  418 root       0:02 tee /tmp/nginx/debug_log.log
3557 root       0:00 grep tee
Run Code Online (Sandbox Code Playgroud)

我有一个函数可以监视tee生成的日志的大小,并在日志达到一定大小时终止tee命令:

monitor_debug_log_size() {
                ## Monitor the file size of the debug log to make sure it does not get too big
                while true; do
                                cecho r "CHECKING DEBUG LOG SIZE... "
                                debugLogSizeBytes=$(stat -c%s "/tmp/nginx/debug_log.log")
                                cecho r "DEBUG LOG SIZE: $debugLogSizeBytes"
                                if [ $((debugLogSizeBytes)) -gt 100000 ]; then
                                                cecho r "DEBUG LOG HAS GROWN TO LARGE... "
                                                sleep 3
                                                #rm -rf /tmp/nginx/debug_log.log 1>/dev/null 2>/dev/null
                                                kill -9 `pgrep -f tee`
                                fi
                                sleep 30
                done
}
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,杀死tee命令也会被 start.sh 实例杀死。为什么是这样?如何结束tee命令但让我的 start.sh 继续运行?谢谢。

Wil*_*ard 35

tee终止时,提供给它的命令将继续运行,直到它尝试写入更多输出。然后它将获得一个 SIGPIPE(在大多数系统上为 13)以尝试写入没有读取器的管道。

如果您修改脚本以捕获 SIGPIPE 并采取一些适当的操作(例如,停止写入输出),那么您应该能够在 tee 终止后让它继续。


更重要的是,而不是杀死tee 所有,使用logrotatecopytruncate用于简单的选择。

引用logrotate(8)

copytruncate

创建副本后原地截断原始日志文件,而不是移动旧日志文件并可选择创建新日志文件。当某些程序无法被告知关闭其日志文件并因此可能永远继续写入(附加)到前一个日志文件时,可以使用它。请注意,复制文件和截断文件之间的时间片非常短,因此可能会丢失一些日志记录数据。使用此选项时,创建选项将无效,因为旧日志文件保留在原处。

  • 您还需要使用 `tee -a` 作为 `tee` 以追加模式打开文件,否则,tee 将在您截断文件后以相同的偏移量继续写入文件(并且在没有支持像 macOS 这样的稀疏文件,它将重新分配文件中导致该位置的部分,占用两倍的磁盘空间)。 (9认同)
  • 其他选项是通过管道传送到 `logger -s` 以便 syslog 处理日志记录(`-s` 也打印在 stderr 上)。 (4认同)
  • 或者在使用 systemd 和 journald 的系统上,使用 systemd-cat 而不是 logger。然后你可以免费获得大量的输出过滤和旋转。 (2认同)