shell获取时间的相关命令
说明:在进行一些性能测试的时候,有时候我们希望能计算一个程序运行的时间,有时候可能会自己写一个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/sgeng2
real 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
#
#time pwd
/home/sgeng2 real 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/sgeng2
real 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/sgeng2
real 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/sgeng2
real 0m0.000s
user 0m0.000s
sys 0m0.000s
#
#time pwd
/home/sgeng2 real 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/sgeng2 real 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/sgeng2 real 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
#
#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
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=$1
end=$2
start_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 $end
time=$(( ( 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
#! /bin/bash
#filename: test.sh # arg1=start, arg2=end, format: %s.%N
function getTiming() {
start=$1
end=$2 start_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 $end time=$(( ( 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
#
#./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进制。
shell获取时间的相关命令的更多相关文章
- linux中用shell获取时间,日期
linux中用shell获取昨天.明天或多天前的日期:在Linux中对man date -d 参数说的比较模糊,以下举例进一步说明:# -d, --date=STRING display time d ...
- linux在shell date获取时间的相关操作
获得当天的日期 date +%Y-%m-%d 输出: 2011-07-28 将当前日期赋值给DATE变量DATE=$(date +%Y%m%d) 有时候我们需要使用今天之前或者往后的日期,这时可以使用 ...
- linux shell获取时间
获得当天的日期 date +%Y-%m-%d 输出: 2011-07-28 将当前日期赋值给DATE变量DATE=$(date +%Y%m%d) 有时候我们需要使用今天之前或者往后的日期,这时可以使用 ...
- shell 获取时间
获取当前时间 t=$(date +"%Y-%m-%d %H-%M-%S") echo $t 获取前一天的当前时间 time=$(date -d "-1 day" ...
- Shell获取时间,日期,上月,当月,下月
#当前日期 $ date +%F #当前时间$ date +"%F %H:%M:%S" #昨日$ date -d yesterday +%F #上一个月 $ date -d &qu ...
- Shell编程基础教程5--文本过滤、正则表达式、相关命令
5.文本过滤.正则表达式.相关命令 5.1.正则表达式(什么是正则表达式?正则表达式怎么进行匹配?常用命令) 简介: 一种用来描述文本模式的特殊语法 ...
- [ SHELL编程 ] 编程常用的ORACLE相关命令
本文主要描述shell编程中常用的Oracle相关命令. 1.sqlplus -L/-S参数 sqlplus -L user/password #-L参数表示用户只尝试登录一次, 而不是在出错时再次提 ...
- adb & adb shell 相关命令
在Mac上配置adb命令 在Mac OS中使用adb命令时,应进行变量配置,步骤如下: 一.终端中输入 cd ~ 二.输入touch .bash_profile 回车 touch:如果没有,则创建文件 ...
- linux在shell中获取时间
linux在shell中获取时间 获得当天的日期 date +%Y-%m-%d 输出: 2011-07-28 将当前日期赋值给DATE变量DATE=$(date +%Y%m%d) 有时候我们需要使用今 ...
随机推荐
- C#注册表操作类(完整版) 整理完整
/// <summary> /// 注册表基项静态域 /// /// 主要包括: /// 1.Registry.ClassesRoot 对应于HKEY_CLASSES_ROOT主键 /// ...
- .net core 2.0 mvc 初步学习
mvc_study *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !impor ...
- windows phone 8.0 app 移植到windows10 app笔记
8.0 public class Convisibility : IValueConverter { public object Convert(object value, Type targetTy ...
- dubbo事件通知机制(1)
此文已由作者岳猛授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. dubbo事件通知机制:http://dubbo.io/books/dubbo-user-book/demos ...
- 十一、linux文件系统权限详解
对于文件系统权限,我们前面已经讲解了一部分,这里就不在重复了. 1.修改文件权限有两种,一种是数字.一种是字母 (chmod 的修改只能是属主或者root) 数字: 修改目录权限和目录内所有文件的权限 ...
- “全栈2019”Java多线程第二章:创建多线程之继承Thread类
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- kali linux之无线渗透
无线技术变化大,难度大,既新鲜刺激,又压力山大.一半协议 一半理论 无线技术特点: 行业发展迅猛 互联网的重要入口 边界模糊 安全实施缺失而且困难 对技术不了解造成配置不当 企业网络私自接入ap破坏 ...
- HTML02--引用样式、表格、列表、div布局
接上一篇“HTML01随笔” 1.使用样式: 内联样式:标签中使用style属性 内部样式:<head>使用<style type="text/css" ...
- jenkins+appium android app自动化测试
jenkins安装 pytest+jenkins安装+allure报告 新建任务 其他默认,保存 立即构建 test_login.py from src.pages import login_page ...
- dubbo学习笔记:快速搭建
搭建一个简单的dubbo服务 参考地址: dubbo官网:http://dubbo.apache.org/zh-cn/docs/user/references/registry/zookeeper.h ...