功能:tail命令能够输出文件的尾部内容,默认状况下它显示文件的最后十行。
显示每一个指定文件的最后10 行到标准输出。若指定了多于一个文件,程序会在每段输出的开始添加相应文件名做为头。若是不指定文件或文件为"-" ,则从标准输入读取数据。
它经常使用来动态监视文件的尾部内容的增加状况,好比用来监视日志文件的变化。node
语法:tail [选项] [文件]
短选项 | 长选项 | 涵义 |
---|---|---|
-c[+] K | --bytes=[+] K | 输出最后 K 字节;另外,使用-c +K 从每一个文件的第 K 字节输出 |
-n[+] K | --lines=[+] K | 输出最后 K 行,代替最后10 行;使用-n +K 从每一个文件的第 K 字节输出 |
-f | --follow=descriptor --follow=name |
descriptor是 --follow 默认值,因此 -f 等价 --follow 等价--follow=descriptor 即时输出文件变化后追加的数据。 tail -f file 动态跟踪文件file的增加状况,tail会每隔一秒去检查一下文件是否增长新的内容。若是增长就追加在原来的输出后面显示。但这种状况,必须保证在执行tail命令时,文件已经存在。若是想终止 tail -f 输出,按 Ctrl+C 中断tail程序。若是按Ctrl+C不能中断输出,那么能够在别的终端上执行 killall tail 强行终止。 |
--pid=PID | 同 -f 使用,当 PID 所对应的进程死去后,终止。 | |
---retry | 即便目标文件不可访问依然试图打开;在与参数-f 或 --follow=name 同时使用时经常有用。 | |
-F | --follow=name --retry | 与 -f 相同,也是动态跟踪文件的变化,不一样的是执行此命令时文件能够不存在。 |
--max-unchanged-stats=N | N 默认为5,使用--follow=name,从新打开一个在 N 次迭代后没有改变大小的文件来看它是否被解除链接或重命名(这是循环日志文件的一般状况)。 因为有inotify,这个选项不多使用。 |
|
-s S | --sleep-interval=S | 与 -f 合用,表示在每次反复的间隔休眠 S 秒 对于 --pid=PID ,每隔 S 秒检查进程。 |
-q | --quiet 或 --silent | 不输出文件名 |
-v | --verbose | 老是输出给出文件名的首部 |
测试的文件内容以下[quietheart@lv-k tail_test]$ 1 04_libraryTest 2 a.out 3 a.out.symbol 4 autotools 5 core.31058 6 cpp_test 7 download_blog 8 gpg_test 9 hello-1.0.tar.gz 10 hello-2.0 11 hello-2.0.tgz 12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test 显示文件的最后10行 [quietheart@lv-k tail_test]$显示文件tail_test的最后10行7 download_blog 8 gpg_test 9 hello-1.0.tar.gz 10 hello-2.0 11 hello-2.0.tgz 12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test 显示文件的最后N行 [quietheart@lv-k tail_test]$显示文件tail_test的最后5行12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test 从第5行开始显示文件 [quietheart@lv-k tail_test]$注意指定的数字前面 + 表明从这个数字相应的位置开始,显示后面的内容5 core.31058 6 cpp_test 7 download_blog 8 gpg_test 9 hello-1.0.tar.gz 10 hello-2.0 11 hello-2.0.tgz 12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test 显示文件最后38个字节的内容 [quietheart@lv-k tail_test]$ ynctest 15 tail_ 16 tail_test 显示文件第38个字节开始以后的内容 [quietheart@lv-k tail_test]$ 3 a.out.symbol 4 autotools 5 core.31058 6 cpp_test 7 download_blog 8 gpg_test 9 hello-1.0.tar.gz 10 hello-2.0 11 hello-2.0.tgz 12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test注意指定的数字前面 + 表明从这个数字相应的位置开始,显示后面的内容。cat tail_testtail tail_testtail -n 5 tail_testtail -n +5 tail_testtail -c 38 tail_testtail -c +38 tail_test
默认是以文件描述符方式,跟踪文件的增加 [quietheart@lv-k tail_test]$此时等价于命令7 download_blog 8 gpg_test 9 hello-1.0.tar.gz 10 hello-2.0 11 hello-2.0.tgz 12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test这里,输入以后,显示默认的文件的后10行,可是tail并无所以而结束,而是一直在运行着,保持这那个文件对应的索引节点的打开状态。 接下来 若是使用 ,向文件追加新内容。那么会看到tail又继续将追加的内容打印出来。 若是使用 ,清空原内容并从新写入新内容。那么tail会输出相似"tail: tail_test: file truncated"的字样来告诉文件内容被truncated了。tail -f tail_test--follow=descriptor tail_testecho new >>tail_testecho new > tail_test
这个命令用于:跟踪动态增加的文件。例如系统日志。在默认状况下,根据它本身的文件描述符号来跟踪文件。
可是,有的程序追加文件内容的时候会将文件删除而后新创建一个。例若有些日志程序会在必定的时候将追加的日志文件重命名,而后再创建一个以前同名的新日志文件追加新的内容,这样的话这个命令就很差用了。再例若有些编辑器例如vim进行修改文件的时候,没法跟踪其变化。经过"ls -il"对vim编辑以前的文件和以后的文件的inode号对比发现,二者不一样,应当是编辑的时候先删除文件的索引节点再新创建一个,新建的节点内容才包含了最新的内容,而以前tail打开的那个索引节点已经被删除了,看不见了,因此固然不会发生变化。
若是想要肯定那么就先用"ps -aux |grep tail"找到tail的进程号,进入/proc目录的tail进程号目录中,查看其fd文件中的某个描述符号,例如"cat 3"这样会发现原来的内容。 mysql
以文件名方式,跟踪文件增加 [quietheart@lv-k tail_test]$ 7 download_blog 8 gpg_test 9 hello-1.0.tar.gz 10 hello-2.0 11 hello-2.0.tgz 12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test这样,tail根据文件名称跟踪文件的变化,默认来讲tail就根据它本身的文件描述符号来跟踪文件,就像前面所说的,有的程序追加文件内容的时候会将文件删除而后新创建一个,例若有些日志程序会在必定的时候将追加的日志文件重命名,而后再创建一个以前同名的新日志文件追加新的内容,那么默认的方式就没法跟踪到文件的变化了,由于文件描述符号是表明一个索引节点的,而新追加的内容可能追加到新的索引节点上面了,这个时候就使用这个 --follow=name 选项。这样,若是当文件新追加内容是追加到同一名称的不一样索引节点的状况发生时,那么tail那里就会提示 "tail: “tail_test” has been replaced; following end of new file"以后,再从新显示追加以后的新的最后10行。tail --follow=name tail_test
tail -f 和tail -F 的区别
-f 参数,若是在追踪此文档时,此文档被删除、转移或者重建了, 那就中止不会再输出了。
-F 参数,若是在追踪此文档时,此文档被删除、转移或者重建了, 那会再从新try那個同名的那個文档, 若是重建了, 会继续追踪此文档。web
-f 是--follow[=HOW]的缩写。"[=HOW]"有两个写法,一个"=descriptor",另外一个是"=name"。[=HOW]省略时,默认使用的是"--follow=descriptor"。-f 等价 -follow 等价--follow=descriptor。第一个窗口[root@cftest2 ~]# helll test2第二个窗口[root@cftest2 ~]# rm: remove regular file `messages.3'? y [root@cftest2 ~]# echo "helll test3">>messages.3可是第一个窗口的tail -f 命令不会出现 hello test3tail -f messages.3rm messages.3
descriptor 虽然是默认的参数,可是不必定是最有用的。好比在tail 一个log文件的时候,这个文件极可能是按照日期或者大小滚动,文件滚动以后这个tail -f 命令,就失效了。
若是你跟踪的文件被被删除、转移或者重建, 你还想继续tail它, 你可使用这个 tail --follow=name 或者 tail -F sql
-F 是 -follow=name --retry 的缩写。--follow=name 是按照文件名跟踪文件,能够按期去从新打开文件检查文件是否被其它程序删除并从新创建。 --retry 这个参数,保证文件从新创建后,能够继续被跟踪。第一个窗口[root@cftest2 ~]# helll test1 tail: `messages.3' has become inaccessible: No such file or directory tail: `messages.3' has appeared; following end of new file helll test2第二个窗口[root@cftest2 ~]# rm: remove regular file `messages.3'? y [root@cftest2 ~]# echo "helll test3">>messages.3第一个窗口能够看到,中间删除了messages.3,但从新建立后并输入helll test2,会继续显示出来。tail -F messages.3rm messages.3
tail -F功能的强大,它等同于--follow=name --retry。若是你跟踪的文件被移动或者更名后, 你还想继续tail它, 你可使用这个选项。
tail手册页中关于--retry的说明:keep trying to open a file even if it is inaccessible when tail starts or if it becomes inaccessible later; useful when following by name, i.e., with --follow=name。 tail命令开始执行时文件不存在或者执行过程当中文件不能访问,会不断重试。
关于--follow的说明:-f, --follow[={name|descriptor}] output appended data as the file grows; -f, --follow, and --follow=descriptor are equivalent 。--follow=descriptor代表跟踪的是文件描述符,--follow=name代表跟踪的是文件名称。
若是文件名称改掉以后,还想继续跟踪原文件名称对应的尾部内容,就得使用 -F 选项而不是 -f 选项了。vim
[root@web imx_server]# 14:13:28.892 INFO ImxConnection[6] imx.server.ImxConnection - RX IMX_ACTIVE_TEST{seq=3460,client_id=1291343201649042,presence_status=1(presence_status_online),} 14:13:28.892 DEBUG ImxConnection[6] org.logicalcobwebs.proxool.ImxDB - 006417 (01/02/00) - Connection #9 served 14:13:28.892 INFO ImxConnection[6] imx.dbo.ImxOnlineInfoRow - EXEC SQL UPDATE imx_online_info SET last_active_time = '2010-12-03 14:13:28.0' WHERE account = 'zhy' 14:13:28.894 DEBUG ImxConnection[6] org.logicalcobwebs.proxool.ImxDB - UPDATE imx_online_info SET last_active_time = '2010-12-03 14:13:28.0' WHERE account = 'zhy'; (1 milliseconds) 14:13:28.894 DEBUG ImxConnection[6] org.logicalcobwebs.proxool.ImxDB - 006417 (00/02/00) - Connection #9 returned (now AVAILABLE) 14:13:29.625 INFO ImxConnection[6] imx.server.ImxConnection - RX IMX_ACTIVE_TEST{seq=3461,client_id=1291343201649042,presence_status=1(presence_status_online),} 14:13:29.626 DEBUG ImxConnection[6] org.logicalcobwebs.proxool.ImxDB - 006418 (01/02/00) - Connection #8 served 14:13:29.626 INFO ImxConnection[6] imx.dbo.ImxOnlineInfoRow - EXEC SQL UPDATE imx_online_info SET last_active_time = '2010-12-03 14:13:29.0' WHERE account = 'zhy' 14:13:29.627 DEBUG ImxConnection[6] org.logicalcobwebs.proxool.ImxDB - UPDATE imx_online_info SET last_active_time = '2010-12-03 14:13:29.0' WHERE account = 'zhy'; (0 milliseconds) 14:13:29.653 DEBUG ImxConnection[6] org.logicalcobwebs.proxool.ImxDB - 006418 (00/02/00) - Connection #8 returned (now AVAILABLE) [root@web imx_server]# 总结一下:要想跟踪会改名的日志的话,用tail -F 而不是tail -f tail -F log/IMX.LOGCtrl+C