【发布时间】:2011-10-13 06:37:51
【问题描述】:
我需要一个解决方案来创建一个脚本来跟踪一个在达到一定大小后重新创建(同名)的日志文件。
使用“tail -f”会导致在重新创建/旋转文件时停止拖尾。
我想做的是创建一个脚本,该脚本会拖尾文件并在它达到 100 行之后,然后重新启动命令......或者更好地在重新创建文件时重新启动命令?
有可能吗?
【问题讨论】:
我需要一个解决方案来创建一个脚本来跟踪一个在达到一定大小后重新创建(同名)的日志文件。
使用“tail -f”会导致在重新创建/旋转文件时停止拖尾。
我想做的是创建一个脚本,该脚本会拖尾文件并在它达到 100 行之后,然后重新启动命令......或者更好地在重新创建文件时重新启动命令?
有可能吗?
【问题讨论】:
是的!使用这个(重试将在文件不存在或无法访问时进行尾部重试,而不仅仅是失败 - 例如可能在您更改文件时):
tail -f --retry <filename>
或
tail --follow=name --retry
或
tail -F <filename>
【讨论】:
/logs。这是故意的吗?如果该文件不存在或您没有权限,您将收到错误消息。但是,对于--retry,它将继续尝试,直到文件存在或您有权访问它。先用当前目录下的测试文件试一下。
--retry 选项。
tail 的GNU 版本。安装:brew install coreutils。与:gtail -f --follow=name --retry <filename> 一起使用(gnu utils 以 g 为前缀,以免与 macOS 核心工具冲突。)
尝试运行
watch "tail -f" yourfile.log
【讨论】:
如果 tail -F not 可用,并且您正尝试从 logrotate 中恢复,您可以将 copytruncate 选项添加到您的 logrotate.d/ 规范文件中,以便不是每次旋转后都创建一个新文件,而是保留并截断文件,同时旋转出一个副本。
这样,旧文件句柄将继续指向新的(truncated) 日志文件,其中追加了新日志。
请注意,在此copy-truncate 过程中可能会丢失一些数据。
【讨论】:
由于您没有支持所有功能的尾部,并且由于您没有手表,因此您可以使用无限循环的简单脚本来执行尾部。
#!/bin/bash
PID=`mktemp`
while true;
do
[ -e "$1" ] && IO=`stat -c %i "$1"`
[ -e "$1" ] && echo "restarting tail" && { tail -f "$1" 2> /dev/null & echo $! > $PID; }
# as long as the file exists and the inode number did not change
while [[ -e "$1" ]] && [[ $IO = `stat -c %i "$1"` ]]
do
sleep 0.5
done
[ ! -z $PID ] && kill `cat $PID` 2> /dev/null && echo > $PID
sleep 0.5
done 2> /dev/null
rm -rf $PID
您可能希望使用陷阱干净地退出此脚本。这取决于你。
基本上,此脚本检查 inode 编号(使用 stat -c %i "$1")是否更改以终止 tail 命令并在重新创建文件时启动一个新命令。
注意:您可能会摆脱会污染您的输出的echo "restarting tail"。它只对测试有用。如果在我们检查 inode 号之后和开始尾部进程之前替换文件,也可能会出现问题。
【讨论】: