说明:在进行一些性能测试的时候,有时候我们希望能计算一个程序运行的时间,有时候可能会自己写一个shell脚本方便进行一些性能测试的控制(比如希望能运行N次取平均值等),总之,这其中有一个需求可能就是获取一个时间戳或时间差。

1. Linux shell获取时间的相关命令

time命令:获取一个程序的执行时间,可以获取到实际运行时间以及程序在用户态和内核态分别的时间,大部分的性能测试,可能只需要关注实际时间。

time命令的使用就很简单了,在原有的要运行的程序(可执行文件、脚本等任何可执行程序)之前加上time即可。

问题一:time命令的常用选项

使用time,常用的选项是:-f和-p。其中-f后面指定一个格式串,控制time的输出的格式,默认的time输出是real、user、sys三行以xmxxx.xxxs的格式输出,通过-f可以控制。

-p选项也是格式,表示使用posix标准的格式,主要的区别是显示的时间都是以s为单位的,具体关于格式的问题参考man time的帮助内容就知道了。

PS:-f选项没法工作?弄不清楚为何-f和-o等选项都无法工作,知道的请补充。(-p是工作的)

另一种控制格式的方法是设置TIMEFORMAT环境变量,具体参考man time可以知道这些格式控制符分别表示什么。举例如下:

#time pwd
/home/sgeng2real    0m0.000s
user    0m0.000s
sys 0m0.000s
#export TIMEFORMAT="real time %E, user time %U,sys time %S"
#time pwd
/home/sgeng2
real time 0.000, user time 0.000,sys time 0.000
#time -p pwd
/home/sgeng2
real 0.00
user 0.00
sys 0.00
#

PS:很奇怪,感觉time的有些格式和上面的选项一样,好像不完全工作,总之,关系不大,格式并不重要,一般使用-p以秒作为单位就足够了。

问题二:time命令的输出的问题

上面已经说到,好像-o选项并不工作,那么,我们就只能自己想办法了。有时候写脚本,就希望把time的结果输出到文件中,然后可能会根据time的输出进行一些处理,比如提取出real时间等。显然,大家能想到的是重定向了,至于重定向的使用这里显然不准备讨论(太复杂),只是提示一点:time命令的输出结果是输出到stderr的,不是stdout,所以进行重定向的时候要注意了。看懂下面的例子基本就能理解了:

#time pwd
/home/sgeng2real    0m0.000s
user    0m0.000s
sys 0m0.000s
#time pwd > out.txt real 0m0.000s
user    0m0.000s
sys 0m0.000s
#cat out.txt
/home/sgeng2
#time pwd 2> out.txt
/home/sgeng2real    0m0.000s
user    0m0.000s
sys 0m0.000s
#cat out.txt
#(time pwd) 2> out.txt
/home/sgeng2
#cat out.txt real   0m0.000s
user    0m0.000s
sys 0m0.000s
#(time pwd) >& out.txt
#cat out.txt
/home/sgeng2real    0m0.000s
user    0m0.000s
sys 0m0.000s
#

PS:这里更多的是涉及到的和重定向相关的内容,所以不会详细分析每一个例子。说明的是注意time pwd 2> out.txt和(time pwd) 2> out.txt的区别,前面一个的含义是把pwd的结果stderr重定向到out.txt,相当于"time (pwd 2> out.txt)"的结果。

date命令

关于date命令的使用,百度一把一大堆,就不重复了,例如可以参考:http://xingfujie.blog.51cto.com/2791569/637223

这里只说明一下几个常见的问题:

问题一:date的%s和%N

date中有很多控制格式的,其中%s是获取当前时间距离1970-01-01 00:00:00 UTC的时间差。date的其它很多格式控制都是控制当前时间的输出格式而已,比如只输出时分秒,只输出年月日等等,其中%N也是这一类,%N输出的是当前时间的纳秒部分,由于date并没有毫秒等级别的输出,所以在秒以下的内容都属于纳秒部分。所以从这个角度说,date是可以很精确的,可以达到纳秒级别。

问题二:获取一个时间戳

有时候会使用时间戳,或者随机数,UUID这样的东西,百度一下也有相关文章(比如搜索”shell date随机数“等)。一般来说,可以用%s和%N组合的方式就没问题,同一秒内,两次运行%N肯定不会一样,所以%s和%N组合能得到一个唯一数。

#date +%s.%N
1337435374.969263560
#date +%s+%N
1337435377+310281496
#date +%s_%N
1337435381_209334510
#date +%s_%N
1337435383_169263078
#date +%s_%N
1337435383_830009679
#

PS:有时候可能希望用一个”唯一“的东西来对文件命名等,就可以加上时间戳了。

2. Linux shell获取时间差(使用date命令)

至于使用time命令,其本身就是获取一个时间差,但是显然,time只适用于一些简单的情况,因为后面的参数是可以执行的内容,有时候可能需要执行多条命令,用time就比较麻烦。

(1) 秒为单位

date获取的是”当前时间“,显然,两次运行date就可以得到一个时间差,理论上,可以使用很多格式来表示date的输出,从而计算时间差,但是,显然,最直接的方式就是使用%s了,这样直接就可以计算出一个时间差,不需要那么复杂的shell字符串处理了。如下:

#start=$(date +%s) && sleep 2 && end=$(date +%s) && echo $(( $end - $start ))
2
#start=$(date +%s) && sleep 3 && end=$(date +%s) && echo $(( $end - $start ))
3
#

当然,这里是在terminal中测试的,所以用&&连续执行这些命令,对于脚本,一行一行的写就很好了。。。。

start=$(date +%s)
...what to do for timing...
end=$(date +%s)
time=$(( $end - $start ))
echo $time

(2) ms为单位

更多的性能测试等场合获取时间差,有可能希望精确到ms。事实上,使用date是可以达到ms的。直接上代码吧。

#! /bin/bash
#filename: test.sh# arg1=start, arg2=end, format: %s.%N
function getTiming() {start=$1end=$2start_s=$(echo $start | cut -d '.' -f 1)start_ns=$(echo $start | cut -d '.' -f 2)end_s=$(echo $end | cut -d '.' -f 1)end_ns=$(echo $end | cut -d '.' -f 2)# for debug..
#    echo $start
#    echo $endtime=$(( ( 10#$end_s - 10#$start_s ) * 1000 + ( 10#$end_ns / 1000000 - 10#$start_ns / 1000000 ) ))echo "$time ms"
}echo "This is only a test to get a ms level time duration..."
start=$(date +%s.%N)
ls >& /dev/null    # hey, be quite, do not output to console....
end=$(date +%s.%N)getTiming $start $end

PS:这个代码是一个简单的测试,可以获取到ls命令执行的时间,相信其执行时间已经够短了,如果你需要获取的时间差在ms以下,相信你不会使用shell了,嘿嘿,自然要靠C去弄了。

结果如下:

#./test.sh
This is only a test to get a ms level time duration...
3 ms
#./test.sh
This is only a test to get a ms level time duration...
2 ms
#./test.sh
This is only a test to get a ms level time duration...
2 ms
#

还满意吧,能获取到这么短的时间。当然,理论上可以获取到以ns为单位的时间差,但是,个人觉得用shell去弄这么小的时间差,你觉得准确么。。。

说明:

上面的代码的思路,其实很简单了,%s为距离标准时间的秒数,%N为当前时间的秒以下的部分,那么显然,%s和%N就表示了当前时间的完整时间戳,两个时间戳就差值就是时间差,问题就是如何处理的问题,大概就是:先使用%s.%N的格式获取到start和end时间,然后利用cut命令从start和end中获取到“.“前面的秒的部分和后面的纳秒的部分(说明:这里的在%s和%N之间插入点,只是作为分隔的作用,任何可能的字符都是可以的,只要能被cut分开就行);然后,用秒的部分相减,得到秒的差值,转换为毫秒的差值;然后,把纳秒的部分转换为毫秒之后求差值(可能为负数);最后,两个差值相加就是真正的以毫秒为单位的差值了。很容易理解,关键是cut的使用,对于shell高手来说,应该有很多方法可以对字符串提取,但是对于我这样的非shell高手,要自己用awk或sed什么的写一个提取的正则,还是很有难度,还好找到了cut命令,能很容易的对这种字符串进行提取。所以:这里的方法仅供参考。。。

关于代码中的“10#”,这是表示后面的数是10进制的数字,之所以需要这个是因为这里的纳秒的前面是以0开头的,shell中好像以0开头会默认认为是八进制,导致运行报错,总之,百度一下就找到了原因,这里就索性把所有的数字都加上了10#,表示都是10进制。

Linux shell获取时间和时间间隔(ms级别)相关推荐

  1. linux获取文件的md5,linux shell 获取文件md5的命令linux操作系统 -电脑资料

    下面我给各位朋友总结一下在linux中利用shell命令来获取文件md5及遍历目录下所有文件的md5的例子,希望此例子对各位同学会有所帮助, 获取文件的MD5值: $ md5sum linuxmint ...

  2. linux shell获取当前执行路径

    linux shell 获取当前正在执行脚本的绝对路径 basepath=$(cd `dirname $0`; pwd) project_path=$(cd `dirname $0`; pwd) pr ...

  3. Linux :: 时间日历指令【1】:date 指令:格式化显示时间信息、Linux 下获取时间

    前言:本篇是 Linux 基本操作篇章的内容! 笔者使用的环境是基于腾讯云服务器:CentOS 7.6 64bit. 学习集: C++ 入门到入土!!!学习合集 Linux 从命令到网络再到内核!学习 ...

  4. linux获取互联网时间,linux中用shell获取时间,日期

    linux中用shell获取昨天.明天或多天前的日期: 在Linux中对man date -d 参数说的比较模糊,以下举例进一步说明: # -d, --date=STRING display time ...

  5. linux中用shell获取时间,日期

    linux中用shell获取昨天.明天或多天前的日期: 在Linux中对man date -d 参数说的比较模糊,以下举例进一步说明: # -d, --date=STRING display time ...

  6. linux的shell键盘输入,linux shell获取键盘输入

    linux shell从键盘获取输入 代码1: #!/bin/bash #提示"Input your choice:",把用户的输入保存入变量choice_user中 read - ...

  7. linux shell 当前时间、过去、未来几天的时间设置

    linux shell 时间设置 文章目录 linux shell 时间设置 一.date 命令含义 二.date 使用命令 1.提取日期元素 1.年月日 2.时分秒 3.星期 4.时间戳 5.日历 ...

  8. Linux Shell 获取端口范围内可用端口

    脚本内容 #!/bin/bash# portRange="80-81" # 可用于读取配置文件 # rangeStart=$(echo ${portRange} | awk -F ...

  9. Linux Shell获取参数的方法

    传参用法 Linux Shell 如何获取参数的方法 $# 是传给脚本的参数个数 $0 是脚本本身的名字 $1 是传递给该shell脚本的第一个参数 $2 是传递给该shell脚本的第二个参数 $@ ...

最新文章

  1. CentOS6.4 利用sendEmail发邮件
  2. Kenshin Cui's Blog
  3. 探索 Java 隐藏的开销
  4. 【李宏毅2020 ML/DL】补充:Meta Learning - Metric-based Approach Train+Test as RNN
  5. mysql writing to net_mysql 提示 Writing to net_MySQL
  6. radius服务器搭建
  7. Java金融计算机计算irr_手把手教你使用金融计算器
  8. Failure [INSTALL_FAILED_INVALID_APK]
  9. java计算机毕业设计H5乡镇疫情防控系统源码+mysql数据库+系统+lw文档+部署
  10. sdutOJ 查字典(Python)
  11. 关于oracle驱动jiar包版本问题导致的ORA-01460【mybatis+Oracle】
  12. 【滤波专题-第3篇】IIR无限冲激响应和FIR有限冲激响应数字滤波器有什么区别?
  13. doc与docx批量互转宏代码
  14. opencv-python数字图像处理学习7:提取一副彩色图像中红色,用HIS模型处理,RGB模型对比显示
  15. [激光原理与应用-21]:《激光原理与技术》-7- 激光技术大汇总与总体概述
  16. 龙人直线电话计费系统
  17. html文本环绕’,css如何使文字环绕显示
  18. 《AI算法工程师手册》
  19. EasyConnect服务器启动失败,建议关闭浏览器后重新登录
  20. 墨尔本大学 计算机科学,墨尔本大学计算机科学硕士专业详解 成为IT大神的必经之路...

热门文章

  1. c语言飞机买票系统,C语言实现飞机订票系统
  2. 数据库表与表的关系(超详细讲解)
  3. 第十三届全国大学生信息安全竞赛(线上初赛)
  4. MAX31855热电偶转换器开发流程
  5. MAX31856中文文档
  6. 【案例】某市数据共享交换平台升级案例
  7. matlab(1)矩阵的输入及运算
  8. 【微积分】算法数学基础之微积分
  9. 创意黑板彩色粉笔PPT模板
  10. IMU预积分--详细推导过程