Note: While performing some performance testing, sometimes we want to calculate the time a program runs, and sometimes it is possible to write a shell script to facilitate some performance test control (such as the wish to run an average of n times, etc.), in short, one of the requirements may be to get a timestamp or time difference.
1. Linux shell command to get time
The time command : Gets the execution time of a program, can obtain the actual running time and the program in the user state and the kernel state respectively, most of the performance test, may only need to pay attention to the actual time.
The use of the time command is simple, and it can be added before the original program to be run (executable, script, and so on).
Issue one: Common options for the time command
The usual options for using time are:-F and-P. Where-F to specify a format string, control the format of the output of time, the default time output is real, user, sys three line in XMXXX.XXXS format output, through-f control.
The-P option is also a format for using the POSIX standard format, and the main difference is that the displayed time is in S, and the specifics about the format refer to the Help content of man time.
PS:-F option not working? It is not clear why the-F and-O options are not working, know please add. (-P is working)
Another way to control the format is to set the TIMEFORMAT environment variable, specifically referring to man time to know what these format controls represent respectively. Examples are as follows:
- #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: Very strange, feel that some of the format of time and the above options, as if not fully work, in short, the relationship is not big, the format is not important, the general use of-p in seconds as the unit is sufficient.
Issue two: Issue with the output of the time command
As mentioned above, as if the-o option does not work, then we can only find our own way. Sometimes writing a script, you want to output the results of the time to a file, and then may be based on the output of time to do some processing, such as the extraction of real times and so on. Obviously, what you can think of is redirection, as for the use of redirects here is obviously not ready to discuss (too complex), just a hint: the output of the time command is output to stderr, not stdout, so be careful when redirecting. Read the following example to understand the basic:
- #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: Here more is involved and redirect related content, so no detailed analysis of each example. Note the difference between time pwd 2> OUT.txt and (time pwd) 2> OUT.txt, the previous meaning is to redirect the results of PWD stderr to OUT.txt, which is equivalent to "time (pwd 2> out.txt)" The result.
Date Command :
About the use of the date command, Baidu a large pile, it is not repeated, for example, you can refer to: http://xingfujie.blog.51cto.com/2791569/637223
Here are just a few common questions to ask:
Issue One: Date's%s and%n
There are many control formats in date, where%s is the time difference between getting the current 1970-01-01 00:00:00 UTC . Many other format control of date is to control the current time of the output format, such as only output time and minute, only the output date and so on, where%n is also this class,%n output is the current time of the nanosecond portion, because the date does not have a millisecond level of output, So the content below the second is the nanosecond part . So from this point of view, date can be very precise and can reach the nanosecond level.
Question two: Get a timestamp
Sometimes use timestamp, or random number, uuid such things, Baidu also has related articles (such as search "Shell date random number", etc.). In general, you can use the combination of%s and%n is no problem, in the same second, two runs%n certainly not the same, so the%s and%n combination can get a unique number.
- #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: Sometimes you may want to use a "unique" thing to name a file, and so on, you can add time stamp.
2. The Linux shell gets the time difference (using the date command)
As for the use of the time command, it is itself getting a time difference, but obviously, time only applies to some simple cases, because the following arguments are what can be done, sometimes it may take more than one command to execute, and time is more troublesome.
(1) seconds
Date gets the "current time", obviously, two times run date can get a time difference, in theory, you can use many formats to represent the output of date, so as to calculate the time difference, but, obviously, the most direct way is to use the%s, so that you can directly calculate a difference, There is no need for such complex shell string processing. As follows:
- #start =$ (date +%s) && sleep 2 && end=$ (date +%s) && echo $ (($end-$start))
- 2
- #start =$ (date +%s) && sleep 3 && end=$ (date +%s) && echo $ (($end-$start))
- 3
- #
Of course, this is tested in terminal, so with && sequential execution of these commands, for the script, a line of writing is very good ....
- start=$ (Date +%s)
- ... what does for timing ...
- end=$ (Date +%s)
- time=$ (($end-$start))
- Echo $time
(2) ms Unit
More performance testing and other occasions to obtain the time difference, it is possible to hope accurate to Ms. In fact, using date can reach Ms. Go directly to the code.
- #! /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) * + (10# $end _ns/1000000-10# $start _ns/1000000)))
- echo "$time MS"
- }
- echo "This was only a test to get a-MS Level time duration ..."
- start=$ (Date +%s.%n)
- LS >&/dev/null # Hey, be quite, does not output to console ....
- end=$ (Date +%s.%n)
- Gettiming $start $end
PS: This code is a simple test, you can get to the LS command execution time, I believe its execution time is short enough, if you need to get the difference in MS below, I believe you will not use the shell, hey, naturally rely on C to get it.
The results are as follows:
- #./test.sh
- This is the only a-test to get a-MS Level time duration ...
- 3 ms
- #./test.sh
- This is the only a-test to get a-MS Level time duration ...
- 2 ms
- #./test.sh
- This is the only a-test to get a-MS Level time duration ...
- 2 ms
- #
Still satisfied, can get to such a short time. Of course, in theory you can get to the time difference in NS, but, the individual think with the shell to get such a small time difference, you feel accurate ...
Description
The idea of the above code, in fact, is very simple,%s is the number of seconds from the standard time,%n is the current time of the next part of the second, then obviously, the%s and%n represents the current time of the full timestamp, the difference between the two timestamps is the time difference, the problem is how to deal with the problem, probably: first Use%s.% n format gets to the start and end time, and then takes the cut command from start and end to "." The part of the previous second and the part of the nanosecond after it (note: Here the insertion point between%s and%n, just as a separate function, any possible characters are possible, as long as the cut can be separated by the line); Then, subtract the seconds, get the difference of seconds, and convert the difference of millisecond. The difference is calculated by converting the part of the nanosecond to milliseconds (possibly negative); Finally, the sum of the two difference values is the true difference in milliseconds. It is easy to understand, the key is the use of cut, for the shell master, there should be many ways to extract the string, but for me such a non-Shell master, to myself with awk or sed what to write an extract of the regular, or very difficult, fortunately found the cut command, This kind of string can be easily extracted. So: Here's the method for reference only ...
About the "10#" in the code, this is to indicate that the next number is a 10-digit number, the reason for this is because the front of the nanosecond is 0 beginning, the shell as if 0 will default to be considered as eight, resulting in running an error, in short, Baidu a bit to find the reason, Here it simply adds all the numbers to the 10#, indicating that they are all 10 binary.
linux--Get Execution time