tail监控⽇志⽂件
ail命令可以输出⽂件的尾部内容,默认情况下它显⽰⽂件的最后⼗⾏。它常⽤来动态监视⽂件的尾部内容的增长情况,⽐如⽤来监视⽇志⽂件的变化。与tail命令对应的是head命令,⽤来显⽰⽂件头部内容。
常⽤参数
格式:tail file
输出指定⽂件file的尾部内容,默认输出最后⼗⾏内容(output the last part of files。Print  the  last 10 lines of each FILE to standard output.)
格式:tail file1 file2 ...
指定多个⽂件时,会显⽰每个⽂件的⽂件名称,再显⽰该⽂件的尾部内容(With more than one FILE, precede each with a header giving the file name.)
格式:tail
格式:tail -
不指定⽂件时,表明从标准输⼊读取内容,这通常⽤在管道线后⾯,把前⼀个命令的输出作为tail的输⼊内容(With no FILE, or when FILE is -, read standard input.)
格式:tail -n file
格式:tail -n n file
格式:tail --lines=n
显⽰⽂件最后n⾏,⽐如tail -20 file就是显⽰⽂件最后10⾏,这个参数可以配合其他参数与使⽤。注意上⾯三种格式的斜体n是实际要显⽰的⾏数的数值。
注意:tail -n可以显⽰最后n⾏的⽂本内容。那么有没有⼀种⽅式显⽰从n⾏开始的⽂本内容,答案是肯定的。
tail -n +4 file表⽰显⽰⽂件file从第4⾏开始的内容。从1开始计数。
格式:tail -f file
动态跟踪⽂件file的增长情况(output appended data as the file grows),tail会每隔⼀秒去检查⼀下⽂
件是否增加新的内容,如果增加就追加在原来的输出后⾯显⽰。但这种情况,必须保证在执⾏tail命令时,⽂件已经存在。
如果想终⽌tail -f的输出,按Ctrl+C中断tail程序即可。如果按Ctrl+C不能中断输出,那么可以在别的终端上执⾏killall tail强⾏终⽌。
注意:采⽤tail -f来监控⽂件变化情况时,在某些情况会不太灵。⽐如在java应⽤程序中采⽤log4j⽇志时,每隔1个⼩时⽣成⼀个新的⽇志⽂件,当前的⽇志输出在LOG4J.LOG中,当⼀个⼩时过去后,log4j会将LOG4J.LOG改名成-mm-dd-HH的形式。那么这个时候tail -f就不能动态输出新的⽇志内容了。tail命令本⾝提供了很多参数,似乎都不能完美的解决这个问题。最后只好编写了⼀个脚本ftail.sh来跟踪⽇志,详见《》。刚才我仔细查看了tail的⼿册页,发现tail -F就能够做到跟踪这种类型的⽇志。转念⼀想,这种需求应该早就被Linux世界的⼈给满⾜了的。
格式:tail -F file
格式:tail --follow=name --retry file
功能与tail -f file相同,也是动态跟踪⽂件的变化,不同的是执⾏此命令时⽂件可以不存在。
以上处理都是针对⽂本⽂件的,下⾯是针对⼆进制⽂件的情形。
格式:tail -c n file
取⽂件file的最后n个字节。
格式:tail -c +n file
取⽂件file的第n个字节后的内容。从1开始计数。
使⽤⽰例
⽰例⼀输出⽂件尾部
先使⽤seq命令输出20个数字保存到1.txt,然后尝试使⽤tail命令。[root@new55 ~]# seq 20 &
[root@new55 ~]#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@new55 ~]#
11
12
13
14
15
16
17
18
19
20
[root@new55 ~]# tail -
18
19
20
[root@new55 ~]# tail -n
18
19
20
[root@new55 ~]# tail --lines=
18
19
20
[root@new55 ~]# tail -n +
14
15
16
17
18
19
20
[root@new55 ~]#
⽰例⼆动态跟踪tomcat输出
动态跟踪tomcat输出。
[root@web logs]# tail -f catalina.out
at org.tor.CoyoteAdapter.service(CoyoteAdapter.java:298)
at http11.Http11Processor.process(Http11Processor.java:852)
at http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at at.util.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)
2010-12-03 13:23:02,236 [http-80-15] i.MhrManager - MhrGetJobReq={seq=991,job_id='86130469-0006'}
2010-12-03 13:23:02,301 [http-80-15] i.MhrManager - MhrGetJobRsp={seq=991,result=0(成功),,info={job_id='86130469-0006',employer_id=86130469,employer_name=⽆锡富⼠时装有限公司,,,job_title='|570309|',job_title0='⽂员',job_type=f(全
职),issue_time='2010-11-03 00:00:00.0',work_address='1902',work_address0=⽆锡市,desired_count='1',,,,,,job_desc=⼤专,1年以上5s管理⼯作经验,电脑操作熟练。,required_experience=1(⼀年以上),,,,required_degree=15(⼤
专),,,,,,,valid_days=30,access_count=12,expire_time='2010-12-03 00:00:00.0',job_status=1(过期),,,,,,contact_name=王⼩
,contact_number=0510-********,remarks='★此职位是从后台导⼊的
',enter_time='2010-11-03 09:45:11.0',change_time=2010-12-03 02:18:05.0,,job_seq=123201,,required_min_age=22,,,accommodations=⾯议,serve_principal=wjw12580,job_summary=⼤专,1年以上5s管理⼯作经验,电脑操作熟练,,}}
2010-12-03 13:23:02,302 [http-80-15] i.MhrManager - MhrGetEmployerReq={seq=0,employer_id='86130469'}
2010-12-03 13:23:02,304 [http-80-15] i.MhrManager - MhrGetEmployerRsp={seq=0,result=0(成功),,info=
{employer_id='86130469',employer_name=⽆锡富⼠时装有限公司,employer_region=1902,employer_address=⽆锡市滨湖镇⼭⽔城科技园8号,,employer_desc=⽆锡富⼠时装(集团)有限公司成⽴于1992年,是中⽇韩合资企业。主要⽣产⾼档针织时装,产品全部外销,连续多年荣获“中国⾏业500强”、“全国⼯业重点⾏业效益⼗佳企业”、“⽆锡市百佳企业”等称号。公司总部位于江苏省⽆锡市滨湖镇⼭⽔城科技园,全新的⼚房设施,占地⾯积30亩。公司分别在苏州、泰兴、盐城、徐州设有分⼚,集团公司现有职⼯1500多⼈,年销售额近3亿元。,,,,,,open_mode=5(系统⾃动操作),open_time='2010-11-03 09:45:10.0',,,,,contact_name=王⼩,contact_number=0510-********,,,,,employer_status=1(已经开
通),,,login_password=871386,,agency=false,balance=100.0000,,,,,serve_principal=wjw12580,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,remarks='此帐号
由“12580zgz-盐城维克多⽹络传媒有限公司”导⼊',enter_time='2010-11-03 09:45:10.0',}}
Ctrl+C
[root@web logs]#
⽰例三动态跟踪log4j⽇志
经过我的试验,发现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选项了。
[root@web imx_server]# tail -F log/IMX.LOG
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)
Ctrl+C
[root@web imx_server]#
总结⼀下:要想跟踪会更名的⽇志的话,⽤tail -F⽽不是tail -f。
⽰例四处理⼆进制⽂件
[root@new55 ~]# seq 20 &
[root@new55 ~]#
1
2
3
4
5log4j与log4j2
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@new55 ~]# hexdump -
00000000  31 0a 32 0a 33 0a 34 0a  35 0a 36 0a 37 0a 38 0a  |1.2.3.4.5.6.7.8.|
00000010  39 0a 31 30 0a 31 31 0a  31 32 0a 31 33 0a 31 34  |9.10.11.12.13.14|
00000020  0a 31 35 0a 31 36 0a 31  37 0a 31 38 0a 31 39 0a  |.15.16.17.18.19.|
00000030  32 30 0a                                          |20.|
00000033
[root@new55 ~]# tail -c | hexdump -C
00000000  0a 31 38 0a 31 39 0a 32  30 0a                    |.18.19.20.|
0000000a
[root@new55 ~]# tail -c - | hexdump -C
00000000  0a 31 38 0a 31 39 0a 32  30 0a                    |.18.19.20.|
0000000a
[root@new55 ~]# tail -c + | hexdump -C
00000000  0a 36 0a 37 0a 38 0a 39  0a 31 30 0a 31 31 0a 31  |.6.7.8.9.10.11.1|
00000010  32 0a 31 33 0a 31 34 0a  31 35 0a 31 36 0a 31 37  |2.13.14.15.16.17|
00000020  0a 31 38 0a 31 39 0a 32  30 0a                    |.18.19.20.|
0000002a
[root@new55 ~]#