tail 源码分析
来源:互联网 发布:伺服阀控制算法 编辑:程序博客网 时间:2024/05/24 04:40
源码: http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/tail.c
使用tail查看日志时可以使用-f
选项实时输出日志中新加入的内容,即follow该文件的内容。像这样,new line
是新加入到文件中的内容,tail可以发现这点并显示给用户:
$ tail -f t1 t2==> t1 <==hello==> t2 <==hello==> t1 <==new linenew line==> t2 <==new line
那么底层是如何实现的呢?
下载了tail的源码,根据选项-f
定位到parse_options。使用F时,follow_mode为Follow_name; 使用f或follow时,默认是Follow_descriptor,否则可以自行指定一种模式。
// parse_options 函数中 case 'F': forever = true; follow_mode = Follow_name; reopen_inaccessible_files = true; break; ... case 'f': case LONG_FOLLOW_OPTION: forever = true; if (optarg == NULL) follow_mode = DEFAULT_FOLLOW_MODE; else follow_mode = XARGMATCH ("--follow", optarg, follow_mode_string, follow_mode_map); break; ...
前面提到的follow的两种模式:Follow_name, Follow_descriptor。Follow_name的意思是,如果文件被重命名了(renamed),那么就用新的文件名重新打开该文件,并跟踪(track)该文件的尾部,适用于日志文件;而Follow_descriptor是说,即便跟踪的文件被重命名或删除也会继续follow该文件。
/* FIXME: make Follow_name the default? */#define DEFAULT_FOLLOW_MODE Follow_descriptor // 默认模式enum Follow_mode{ /* Follow the name of each file: if the file is renamed, try to reopen that name and track the end of the new file if/when it's recreated. This is useful for tracking logs that are occasionally rotated. */ Follow_name = 1, /* Follow each descriptor obtained upon opening a file. That means we'll continue to follow the end of a file even after it has been renamed or unlinked. */ Follow_descriptor = 2};
tail将管理的文件放到一个数组中,每个元素的结构定义为:
struct File_spec{ char *name; // 文件名 /* 上次检查时文件的一些属性,包括大小、inode等*/ off_t size; struct timespec mtime; dev_t dev; ino_t ino; mode_t mode; ... /* 文件描述符,打开失败时为-1 */ int fd; ...};
tail的主循环为tail_forever
, 每隔若干事件对管理的文件数组进行检查,通过fstat检查文件大小或者dev/ino是否改变了。如果都没变,就sleep若干时间后,继续检查:
/* Tail N_FILES files forever, or until killed. The pertinent information for each file is stored in an entry of F. Loop over each of them, doing an fstat to see if they have changed size, and an occasional open/fstat to see if any dev/ino pair has changed. If none of them have changed size in one iteration, sleep for a while and try again. Continue until the user interrupts us. */static void tail_forever (struct File_spec *f, size_t n_files, double sleep_interval){...}
总结一下,tail 实际上是一个循环,每次循环都检测文件是否发生变化,然后把变化告诉用户。
0 0
- tail 源码分析
- tail
- tail
- tail
- tail
- tail
- tail
- libevent中的tail queue详细分析
- 源码分析
- 源码分析
- 源码分析
- 源码分析
- 源码分析
- 源码分析
- 源码分析
- 源码分析
- 源码分析:SparseArray分析
- tail 命令
- oracle编译死锁问题解决
- 基于KVM、Xen、OpenVZ等虚拟化技术的WEB在线管理工具
- 日期加减天数js
- linux所有服务列表
- Java各种设计模式
- tail 源码分析
- 创新不是解难题!
- 服务器站点崩溃的几种原因及解决方案
- man 命令查看 格式解读
- 第二个电商项目Bug点统计和解决方法
- Android 自定义正方形布局
- Android webview使用详解
- minimum-depth-of-binary-tree
- Js函数声明与函数表达式的区别