linux time 命令详解
time命令常用于测量一个命令的运行时间,注意不是用来显示和修改系统时间的(这是date命令干的事情)。但是今天我通过查看time命令的手册页,发现它能做的不仅仅是测量运行时间,还可以测量内存、I/O等的使用情况,手册页上的说法是time a simple command or give resource usage,其中time一词我认为它应该是测量或测定的意思,并不单指时间。一个程序在运行时使用的系统资源通常包括CPU、Memory和I/O等,其中CPU资源的统计包括实际使用时间(real time)、用户态使用时间(the process spent in user mode)、内核态使用时间(the process spent in kernel mode)。但是简单的使用time命令并不能得到内存和I/O的统计数据 ,这里就需要使用第二个time指令 。
一、time用法
time命令最常用的使用方式就是在其后面直接跟上命令和参数:
1time <command> [<arguments...>]
2在命令执行完成之后就会打印出CPU的使用情况:
3real 0m5.064s <== 实际使用时间(real time)
4user 0m0.020s <== 用户态使用时间(the process spent in user mode)
5sys 0m0.040s <== 内核态使用时间(the process spent in kernel mode)
time命令跟上-p参数可以只打印时间数值(秒数),不打印单位。
二、time使用示例
以下使用time进行时间运行统计运行
1[[email protected] /]# time find / -name 'cpuid.h'
2/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include/cpuid.h
3/usr/src/kernels/2.6.32-431.29.2.el6.x86_64/include/config/x86/cpuid.h
4/usr/src/kernels/2.6.32-431.23.3.el6.x86_64/include/config/x86/cpuid.h
5/usr/src/kernels/2.6.32-431.el6.x86_64/include/config/x86/cpuid.h
6/usr/src/kernels/2.6.32-504.8.1.el6.x86_64/include/config/x86/cpuid.h
7real 0m20.186s
8user 0m0.300s
9sys 0m0.849s
10[[email protected] /]# time find / -name 'cpuid.h'
11/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include/cpuid.h
12/usr/src/kernels/2.6.32-431.29.2.el6.x86_64/include/config/x86/cpuid.h
13/usr/src/kernels/2.6.32-431.23.3.el6.x86_64/include/config/x86/cpuid.h
14/usr/src/kernels/2.6.32-431.el6.x86_64/include/config/x86/cpuid.h
15/usr/src/kernels/2.6.32-504.8.1.el6.x86_64/include/config/x86/cpuid.h
16real 0m0.468s
17user 0m0.195s
18sys 0m0.263s
注:
1、一般情况下,real远大于user加上sys,因为find需要遍历各个目录,需要大量的I/O操作,而磁盘I/O通常是最慢的环节,因此大部分时间find进程都在等待磁盘I/O完成。
2、再次运行的时候,发现real time变得很小了,应该是操作系统将刚才操作过的一些文件缓存了的缘故,因而大大减少了磁盘I/O。
3、使用-p参数时,直接打印所需时间的数值,单位为秒,而不是更友好的格式,包括分钟、秒钟的显示方式。
三、另一个 time
Linux系统中time命令其实不止一个看过手册页的朋友,会发现有个-f参数可以来指定统计信息的输出格式,我们也来试一下。
1[[email protected] ~]# time -f "real %f\nuser %f\nsys %f\n" find . -name 'cpuid.h'
2-bash: -f: command not found
3real 0m0.024s
4user 0m0.000s
5sys 0m0.000s
会发现找不到这个指令或参数,使用type -a来看一下。
1# type -a time
2time is a shell keyword
3time is /usr/bin/time
注:通过这条命令我们可以发现我们常用的time其实是一个Shell关键字,还有一个外部命令/usr/bin/time,它有何不同呢?
1# /usr/bin/time
2Usage: /usr/bin/time [-apvV] [-f format] [-o file] [--append] [--verbose]
3 [--portability] [--format=format] [--output=file] [--version]
4 [--help] command [arg...]
注:外部命令/usr/bin/time功能更强大,下面来尝试一下。
1# /usr/bin/time find / -name 'cpuid.h'
2/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include/cpuid.h
3/usr/src/kernels/2.6.32-431.29.2.el6.x86_64/include/config/x86/cpuid.h
4/usr/src/kernels/2.6.32-431.23.3.el6.x86_64/include/config/x86/cpuid.h
5/usr/src/kernels/2.6.32-431.el6.x86_64/include/config/x86/cpuid.h
6/usr/src/kernels/2.6.32-504.8.1.el6.x86_64/include/config/x86/cpuid.h
70.20user 0.25system 0:00.79elapsed 58%CPU (0avgtext+0avgdata 10784maxresident)k
82224inputs+0outputs (0major+1549minor)pagefaults 0swaps
注:注意后面两行,打印了很多信息,但看不太清楚。它有一个参数-v,可以打印得更清楚些。
1[[email protected] /]# /usr/bin/time find / -name 'cpuid.h'
2/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include/cpuid.h
3/usr/src/kernels/2.6.32-431.29.2.el6.x86_64/include/config/x86/cpuid.h
4/usr/src/kernels/2.6.32-431.23.3.el6.x86_64/include/config/x86/cpuid.h
5/usr/src/kernels/2.6.32-431.el6.x86_64/include/config/x86/cpuid.h
6/usr/src/kernels/2.6.32-504.8.1.el6.x86_64/include/config/x86/cpuid.h
70.20user 0.25system 0:00.79elapsed 58%CPU (0avgtext+0avgdata 10784maxresident)k
82224inputs+0outputs (0major+1549minor)pagefaults 0swaps
9[root@91it /]# /usr/bin/time -v find / -name 'cpuid.h'
10/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include/cpuid.h
11/usr/src/kernels/2.6.32-431.29.2.el6.x86_64/include/config/x86/cpuid.h
12/usr/src/kernels/2.6.32-431.23.3.el6.x86_64/include/config/x86/cpuid.h
13/usr/src/kernels/2.6.32-431.el6.x86_64/include/config/x86/cpuid.h
14/usr/src/kernels/2.6.32-504.8.1.el6.x86_64/include/config/x86/cpuid.h
15 Command being timed: "find / -name cpuid.h"
16 User time (seconds): 0.18
17 System time (seconds): 0.25
18 Percent of CPU this job got: 98%
19 Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.45
20 Average shared text size (kbytes): 0
21 Average unshared data size (kbytes): 0
22 Average stack size (kbytes): 0
23 Average total size (kbytes): 0
24 Maximum resident set size (kbytes): 10752
25 Average resident set size (kbytes): 0
26 Major (requiring I/O) page faults: 0
27 Minor (reclaiming a frame) page faults: 1550
28 Voluntary context switches: 1
29 Involuntary context switches: 111
30 Swaps: 0
31 File system inputs: 0
32 File system outputs: 0
33 Socket messages sent: 0
34 Socket messages received: 0
35 Signals delivered: 0
36 Page size (bytes): 4096
37 Exit status: 0
四、time输出重定向
time命令的输出信息是打印在标准错误输出上的, 我们通过一个简单的尝试来验证一下。
1# time find / -name 'cpuid.h' >1.txt
2# time find / -name 'cpuid.h' 2>2.txt
通过上面的尝试,发现无法将time的输出信息重定向到文件里面,为什么?因为time是shell的关键字,shell做了特殊处理,它会把time命令后面的命令行作为一个整体来进行处理,在重定向时,实际上是针对后面的命令来的,time命令本身的输出并不会被重定向的。那现在怎么办呢?网上提供了两种解决方法。
方法1:
将time命令和将要执行的命令行放到一个shell代码块中,也就是一对大括号中,要注意空格和分号的使用。
1[[email protected] /]# {time find . -name 'cpuid.h'} 2>2.txt
好像成功了。慢,看一下对不对。
1[[email protected] /]# cat 2.txt
2-bash: {time: command not found
原来bash把 {time 作为一个整体来处理了,前后都加上空格试试。
1[[email protected] /]# { time find . -name 'cpuid.h' } 2>2.txt
2> Ctrl+C
这次Bash认为命令都没有输入完成,少了分号。因为Bash认为后面的 } 是find命令的参数。
1[[email protected] /]# { time find . -name 'cpuid.h'; } 2>2.txt
2[[email protected] /]# cat 2.txt
3real 0m0.068s
4user 0m0.030s
5sys 0m0.040s
第一种方式的尝试成功了,总结起来就是 { time command-line; } 2>file 注意分隔符的使用。
方法2:
使用子Shell的方式
1[[email protected] /]# (time find / -name 'cpuid.h') 2>2.txt
2[[email protected] /]# cat 2.txt
3real 0m0.083s
4user 0m0.040s
5sys 0m0.020s
总结起来就是 (time command-line) 2>file 这里time紧贴着小括号(也可以的,命令行结束也不必带分号。当然最好还是用第一种方式,毕竟启动一个子shell是要多占些资源的。
捐赠本站(Donate)
如您感觉文章有用,可扫码捐赠本站!(If the article useful, you can scan the QR code to donate))
- Author: shisekong
- Link: https://blog.361way.com/linux-time/4362.html
- License: This work is under a 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. Kindly fulfill the requirements of the aforementioned License when adapting or creating a derivative of this work.