打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
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 <command> [<arguments...>]
在命令执行完成之后就会打印出CPU的使用情况:
real    0m5.064s      <== 实际使用时间(real time)
user    0m0.020s     <== 用户态使用时间(the process spent in user mode)
sys     0m0.040s      <== 内核态使用时间(the process spent in kernel mode)
time命令跟上-p参数可以只打印时间数值(秒数),不打印单位。
使用示例

示例一 统计运行时间

  1. [root@web186 root]# time find . -name "mysql.sh"
  2. ./work186/sms/bin/mysql.sh
  3. ./work186/sms/src/scripts/mysql.sh
  4. ./work186/sms/src/scripts1/mysql.sh
  5. ./work186/sms1/bin/mysql.sh
  6. ./work186/sms1/src/scripts/mysql.sh
  7. ./temp/sms/bin/mysql.sh
  8. ./temp/sms/src/scripts/mysql.sh
  9.  
  10. real    0m14.837s
  11. user    0m0.030s
  12. sys     0m0.120s

[root@web186 root]#
注:real远大于user加上sys,因为find需要遍历各个目录,需要大量的I/O操作,而磁盘I/O通常是最慢的环节,因此大部分时间find进程都在等待磁盘I/O完成。

  1. [root@web186 root]# time find . -name "mysql.sh"
  2. ./work186/sms/bin/mysql.sh
  3. ./work186/sms/src/scripts/mysql.sh
  4. ./work186/sms/src/scripts1/mysql.sh
  5. ./work186/sms1/bin/mysql.sh
  6. ./work186/sms1/src/scripts/mysql.sh
  7. ./temp/sms/bin/mysql.sh
  8. ./temp/sms/src/scripts/mysql.sh
  9.  
  10. real    0m0.230s
  11. user    0m0.040s
  12. sys     0m0.030s

注:再次运行的时候,发现real time变得很小了,应该是操作系统将刚才操作过的一些文件缓存了的缘故,因而大大减少了磁盘I/O。

  1. [root@web186 root]# time -p find . -name "mysql.sh"
  2. ./work186/sms/bin/mysql.sh
  3. ./work186/sms/src/scripts/mysql.sh
  4. ./work186/sms/src/scripts1/mysql.sh
  5. ./work186/sms1/bin/mysql.sh
  6. ./work186/sms1/src/scripts/mysql.sh
  7. ./temp/sms/bin/mysql.sh
  8. ./temp/sms/src/scripts/mysql.sh
  9. real 0.15
  10. user 0.04
  11. sys 0.03

注:使用-p参数时,直接打印所需时间的数值,单位为秒,而不是更友好的格式,包括分钟、秒钟的显示方式。
[root@web186 root]#

示例二 Linux系统中time命令其实不止一个
看过手册页的朋友,会发现有个-f参数可以来指定统计信息的输出格式,我们也来试一下。

  1. [root@web186 root]# time -f "real %f\nuser %f\nsys %f\n" find . -name "mysql.sh"
  2. -bash: -f: command not found
  3.  
  4. real    0m0.024s
  5. user    0m0.000s
  6. sys     0m0.000s

怪哉,不灵啊。使用type -a来看一下。使用这个shell内建命令经常会有意想不到的发现。

  1. [root@web186 root]# type -a time
  2. time is a shell keyword
  3. time is /usr/bin/time

注:通过这条命令我们可以发现我们常用的time其实是一个Shell关键字,还有一个外部命令/usr/bin/time,它有何不同呢?

  1. [root@web186 root]# /usr/bin/time
  2. Usage: /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. [root@web186 root]# /usr/bin/time find . -name "mysql.sh"
  2. ./work186/sms/bin/mysql.sh
  3. ./work186/sms/src/scripts/mysql.sh
  4. ./work186/sms/src/scripts1/mysql.sh
  5. ./work186/sms1/bin/mysql.sh
  6. ./work186/sms1/src/scripts/mysql.sh
  7. ./temp/sms/bin/mysql.sh
  8. ./temp/sms/src/scripts/mysql.sh
  9. 0.03user 0.04system 0:00.12elapsed 55%CPU (0avgtext+0avgdata 0maxresident)k
  10. 0inputs+0outputs (154major+63minor)pagefaults 0swaps

注:注意后面两行,打印了很多信息,但看不太清楚。它有一个参数-v,可以打印得更清楚些。

  1. [root@web186 root]# /usr/bin/time -v find . -name "mysql.sh"
  2. ./work186/sms/bin/mysql.sh
  3. ./work186/sms/src/scripts/mysql.sh
  4. ./work186/sms/src/scripts1/mysql.sh
  5. ./work186/sms1/bin/mysql.sh
  6. ./work186/sms1/src/scripts/mysql.sh
  7. ./temp/sms/bin/mysql.sh
  8. ./temp/sms/src/scripts/mysql.sh
  9. Command being timed: "find . -name mysql.sh"
  10. User time (seconds): 0.03
  11. System time (seconds): 0.05
  12. Percent of CPU this job got: 47%
  13. Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.17
  14. Average shared text size (kbytes): 0
  15. Average unshared data size (kbytes): 0
  16. Average stack size (kbytes): 0
  17. Average total size (kbytes): 0
  18. Maximum resident set size (kbytes): 0
  19. Average resident set size (kbytes): 0
  20. Major (requiring I/O) page faults: 153
  21. Minor (reclaiming a frame) page faults: 64
  22. Voluntary context switches: 0
  23. Involuntary context switches: 0
  24. Swaps: 0
  25. File system inputs: 0
  26. File system outputs: 0
  27. Socket messages sent: 0
  28. Socket messages received: 0
  29. Signals delivered: 0
  30. Page size (bytes): 4096
  31. Exit status: 0
  32. [root@web186 root]#

尝试完这个之后,我看了一下Google搜索的结果,发现有位大虾早已发现了这个秘密,见相关资料【1】。
示例三 解决time命令输出信息的重定向问题
time命令的输出信息是打印在标准错误输出上的, 我们通过一个简单的尝试来验证一下。

  1. [root@web186 root]# time find . -name "mysql.sh" &gt;1.txt
  2.  
  3. real    0m0.081s
  4. user    0m0.060s
  5. sys     0m0.020s
  6. [root@web186 root]# time find . -name "mysql.sh" 2&gt;2.txt
  7. ./work186/sms/bin/mysql.sh
  8. ./work186/sms/src/scripts/mysql.sh
  9. ./work186/sms/src/scripts1/mysql.sh
  10. ./work186/sms1/bin/mysql.sh
  11. ./work186/sms1/src/scripts/mysql.sh
  12. ./temp/sms/bin/mysql.sh
  13. ./temp/sms/src/scripts/mysql.sh
  14.  
  15. real    0m0.068s
  16. user    0m0.040s
  17. sys     0m0.030s

通过上面的尝试,发现无法将time的输出信息重定向到文件里面,为什么?因为time是shell的关键字,shell做了特殊处理,它会把time命 令后面的命令行作为一个整体来进行处理,在重定向时,实际上是针对后面的命令来的,time命令本身的输出并不会被重定向的。那现在怎么办呢?网上提供了 两种解决方法【2,3】,我们一一尝试一下。
第一种解决方法,就是将time命令和将要执行的命令行放到一个shell代码块中,也就是一对大括号中,要注意空格和分号的使用。
[root@web186 root]# {time find . -name “mysql.sh”} 2>2.txt
好像成功了。慢,看一下对不对。
[root@web186 root]# cat 2.txt
-bash: {time: command not found
原来bash把 {time 作为一个整体来处理了,前后都加上空格试试。
[root@web186 root]# { time find . -name “mysql.sh” } 2>2.txt
> Ctrl+C
这次Bash认为命令都没有输入完成,少了分号。因为Bash认为后面的 } 是find命令的参数。

  1. [root@web186 root]# { time find . -name "mysql.sh"; } 2&gt;2.txt
  2. ./work186/sms/bin/mysql.sh
  3. ./work186/sms/src/scripts/mysql.sh
  4. ./work186/sms/src/scripts1/mysql.sh
  5. ./work186/sms1/bin/mysql.sh
  6. ./work186/sms1/src/scripts/mysql.sh
  7. ./temp/sms/bin/mysql.sh
  8. ./temp/sms/src/scripts/mysql.sh
  9. [root@web186 root]# cat 2.txt
  10.  
  11. real    0m0.068s
  12. user    0m0.030s
  13. sys     0m0.040s

第一种方式的尝试成功了,总结起来就是 { time command-line; } 2>file  注意分隔符的使用。
另外一种方式就是使用子Shell的方式,如下所示:

  1. [root@web186 root]# (time find . -name "mysql.sh") 2&gt;2.txt
  2. ./work186/sms/bin/mysql.sh
  3. ./work186/sms/src/scripts/mysql.sh
  4. ./work186/sms/src/scripts1/mysql.sh
  5. ./work186/sms1/bin/mysql.sh
  6. ./work186/sms1/src/scripts/mysql.sh
  7. ./temp/sms/bin/mysql.sh
  8. ./temp/sms/src/scripts/mysql.sh
  9. [root@web186 root]# cat 2.txt
  10.  
  11. real    0m0.083s
  12. user    0m0.040s
  13. sys     0m0.020s
  14. [root@web186 root]#

第二种方式的尝试也成功了,总结起来就是 (time command-line) 2>file 这里time紧贴着小括号(也可以的,命令行结束也不必带分号。当然最好还是用第一种方式,毕竟启动一个子shell是要多占些资源的。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
实战模拟监控MySQL服务shell脚本小结
编译busybox错误汇总
Linux配置开机自启动执行脚本方法 Linux学习
Linux中root安装microsoft R open(MRO),普通用户如何使用?
linux运维初级班课前综合考试及参考答案20110529(判断进程是否存在的小案例)
在 Linux 中使用 Cron 执行定时任务
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服