在Linux管理员的职业生涯中常需要对输出添加时间戳。无论是记录shell脚本还是简单的指令(比如ping
,traceroute
等),时间戳都会派上用场。ts
命令能够简单地完成时间戳的功能。本文将向你展示如何使用ts
命令轻松地将时间戳添加到任何输出中。
要使用ts
命令需要安装moreutils
包。
apt install moreutils
执行环境:Ubuntu 16.04.7 LTS
ts命令为输出添加时间戳
ts
是timestamp
的缩写,会在每一行输出的开始添加时间戳。
如果你单独在shell中输入ts
,它将等待键盘输入。一旦收到一行输入,它将在该行的开头添加一个时间戳,并将其打印到标准输出stdout
。
root@iZwz9czknxjqmstiji1vpmZ:~# ts
hello ts // 输入hello ts
Apr 02 16:20:55 hello ts // 打印时间戳+hello ts
当从管道中得到输入,ts
命令更加有用。比如使用ping
命令通过管道结合ts命令。
root@iZwz9czknxjqmstiji1vpmZ:~# ping www.csdn.net | ts
Apr 02 16:24:23 PING www.csdn.net (47.95.164.112) 56(84) bytes of data.
Apr 02 16:24:23 64 bytes from 47.95.164.112: icmp_seq=1 ttl=94 time=32.7 ms
Apr 02 16:24:24 64 bytes from 47.95.164.112: icmp_seq=2 ttl=94 time=32.8 ms
Apr 02 16:24:25 64 bytes from 47.95.164.112: icmp_seq=3 ttl=94 time=32.8 ms
Apr 02 16:24:26 64 bytes from 47.95.164.112: icmp_seq=4 ttl=94 time=32.8 ms
正如你所看到的,每一行的输入都添加了一个时间戳。你可能会问,这难道不是输出么?是的,它确实是ts
命令的输出。然而是通过管道,将ping
命令的输出作为ts
命令的输入。
ts命令的选项参数
ts
命令只有几个参数选项。这里我们将概述一些选项并给出例子。
增量时间戳
通过-s
或-i
选项可以设置增量时间戳。但是它们在增量的起始位置上有所不同。
-s
选项将从程序或操作开始显示增量时间戳。换句话说,它将显示从启动程序以来的时间。在这里,你将再次看到ping
的例子,这次是增量时间戳。
root@iZwz9czknxjqmstiji1vpmZ:~# ping www.csdn.net | ts -s
00:00:00 PING www.csdn.net (47.95.164.112) 56(84) bytes of data.
00:00:00 64 bytes from 47.95.164.112: icmp_seq=1 ttl=94 time=32.8 ms
00:00:01 64 bytes from 47.95.164.112: icmp_seq=2 ttl=94 time=32.7 ms
00:00:02 64 bytes from 47.95.164.112: icmp_seq=3 ttl=94 time=32.9 ms
00:00:03 64 bytes from 47.95.164.112: icmp_seq=4 ttl=94 time=32.8 ms
00:00:04 64 bytes from 47.95.164.112: icmp_seq=5 ttl=94 time=32.8 ms
-i
选项有一些不同,它显示的时间是自从最后一个时间戳开始计算的。再次使用ping
的例子来说明,加-i
的递增时间戳是从上一个时间戳开始的时间。
root@iZwz9czknxjqmstiji1vpmZ:~# ping -i 3 www.csdn.net | ts -i
00:00:00 PING www.csdn.net (47.95.164.112) 56(84) bytes of data.
00:00:00 64 bytes from 47.95.164.112: icmp_seq=1 ttl=94 time=32.7 ms
00:00:03 64 bytes from 47.95.164.112: icmp_seq=2 ttl=94 time=32.8 ms
00:00:03 64 bytes from 47.95.164.112: icmp_seq=3 ttl=94 time=32.8 ms
00:00:03 64 bytes from 47.95.164.112: icmp_seq=4 ttl=94 time=32.7 ms
ping命令加-i 3
选项表示间隔3s发送一次数据包。这就导致了除了第一次之外的其他时间戳都是3s。
相对时间戳
如果配置了-r
选项,它会将输入中现有的时间戳转换为相对时间,例如“15m5s ago”。这里有一个巧妙的用法,我将用journalctl
命令显示系统的日志。然后,通过管道将其传递给ts
命令,从而将日志中的时间戳转换为相对时间戳。
注意:“Time::Duration” 和“Date::Parse”这两个perl模块需要提前安装,可以参考Linux安装CPAN,并安装“Time::Duration”和“Date::Parse” perl模块文章进行安装。
我们通过journalctl
命令打印最后4行系统日志。
root@iZwz9czknxjqmstiji1vpmZ:~# journalctl -f -n 4
-- Logs begin at Fri 2020-05-22 11:44:34 CST. --
Apr 02 19:17:01 iZwz9czknxjqmstiji1vpmZ CRON[909]: pam_unix(cron:session): session closed for user root
Apr 02 19:25:01 iZwz9czknxjqmstiji1vpmZ CRON[930]: pam_unix(cron:session): session opened for user root by (uid=0)
Apr 02 19:25:01 iZwz9czknxjqmstiji1vpmZ CRON[931]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)
Apr 02 19:25:01 iZwz9czknxjqmstiji1vpmZ CRON[930]: pam_unix(cron:session): session closed for user root
我们再次打印最后4行系统日志,这次通过管道将输出传递给ts -r
,从而转换为相对时间戳。
root@iZwz9czknxjqmstiji1vpmZ:~# journalctl -f -n 4 | ts -r
-- Logs begin at Fri 2020-05-22 11:44:34 CST. --
11m31s ago iZwz9czknxjqmstiji1vpmZ CRON[909]: pam_unix(cron:session): session closed for user root
3m31s ago iZwz9czknxjqmstiji1vpmZ CRON[930]: pam_unix(cron:session): session opened for user root by (uid=0)
3m31s ago iZwz9czknxjqmstiji1vpmZ CRON[931]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)
3m31s ago iZwz9czknxjqmstiji1vpmZ CRON[930]: pam_unix(cron:session): session closed for user root
格式化时间戳
让我们先看下例子。
root@iZwz9czknxjqmstiji1vpmZ:~# echo " - %B 完整打印月份名称" | ts %B
April - %B 完整打印月份名称
root@iZwz9czknxjqmstiji1vpmZ:~# echo " - %s 显示自UNIX时代以来的秒数" | ts %s
1617363439 - %s 显示自UNIX时代以来的秒数
当然你可以结合这些格式化字符串来获取你想要的时间戳。这里有几个更复杂的例子。
root@iZwz9czknxjqmstiji1vpmZ:~# echo " - %l\":\"%M%p 显示12h表示的时间" | ts %l":"%M%p
7:39PM - %l":"%M%p 显示12h表示的时间
root@iZwz9czknxjqmstiji1vpmZ:~# echo " - %%Y-%m-%d 显示年-月-日" | ts %Y-%m-%d
2021-04-02 - %%Y-%m-%d 显示年-月-日
root@iZwz9czknxjqmstiji1vpmZ:~# echo " - %B\" \"%d,%y 用英文表示月 日,年" | ts %B" "%d,%Y
April 02,2021 - %B" "%d,%y 用英文表示月 日,年
你也可以通过-r
选项和格式化参数相结合用来格式化存在的时间戳。让我们看个例子。
这里有一行系统日志,注意它的时间戳。
Apr 02 19:35:01 iZwz9czknxjqmstiji1vpmZ CRON[940]: pam_unix(cron:session): session closed for user root
journalctl
时间戳已经非常友好。 但是,我们可以将它们更改为我们想要的格式。 我们使用%Y-%m-%d" "%l":"%M%p
将它们转换为比较舒服的格式。
root@iZwz9czknxjqmstiji1vpmZ:~# sudo journalctl -f | ts -r %Y-%m-%d" "%l":"%M%p
2021-04-02 8:43PM iZwz9czknxjqmstiji1vpmZ sudo[989]: pam_unix(sudo:session): session opened for user root by root(uid=0)
有关所有格式化参数,请参见strftime。