Note: When performing some performance tests, we sometimes want to calculateProgramSometimes, you may write a shell script to control the performance test (for example, you want to run n times to obtain the average value). In short, one of these requirements may be to obtain a timestamp or time difference.
1. commands related to Linux Shell time Acquisition
Time Command: Get the execution time of a program. You can get the actual running time and the time when the program is in the user State and kernel state respectively. For most performance tests, you only need to pay attention to the actual time.
The use of the Time Command is very simple, just add time before the original program to run (executable files, scripts, and other executable programs.
Question 1: Common options of the Time Command
The commonly used time options are-F and-P. -F is followed by a format string to control the output format of time. The default time output is real, user, and SYS. xxxs format output, which can be controlled through-f.
The-P option is also a format that uses the POSIX standard format. The main difference is that the display time is in seconds, for more information about the format, see man time.
PS:-F option cannot work? You cannot find out why-F and-O options cannot work. (-P is working)
Another way to control the format is to set the timeformat environment variable. For details, refer to man time to know what these format controllers represent. Example:
[Plain] View plaincopyprint?
# Time pwd
/Home/sgeng2
Real 0m0. 000 s
User 0m0. 000 s
Sys 0m0. 000 s
# 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: It's strange that some formats of time are the same as those of the preceding options. They don't seem to work completely. In short, the relationship is not big, and the format is not important, generally, it is enough to use-P in seconds.
Question 2: output of the Time Command
As mentioned above, it seems that the-O option does not work, so we can only find a solution by ourselves. Sometimes, when writing a script, you want to output the time result to the file, and then perform some processing based on the time output, such as extracting the real time. Obviously, what you can think of is redirection. As for the use of redirection, it is obviously not to be discussed here (too complicated). It just prompts that the output result of the Time Command is output to stderr, not stdout, so pay attention to the redirection. You can understand the following example:
[Plain] View plaincopyprint?
# Time pwd
/Home/sgeng2
Real 0m0. 000 s
User 0m0. 000 s
Sys 0m0. 000 s
# Time PWD> out.txt
Real 0m0. 000 s
User 0m0. 000 s
Sys 0m0. 000 s
# Cat out.txt
/Home/sgeng2
# Time PWD 2> out.txt
/Home/sgeng2
Real 0m0. 000 s
User 0m0. 000 s
Sys 0m0. 000 s
# Cat out.txt
# (Time PWD) 2> out.txt
/Home/sgeng2
# Cat out.txt
Real 0m0. 000 s
User 0m0. 000 s
Sys 0m0. 000 s
# (Time PWD)> & out.txt
# Cat out.txt
/Home/sgeng2
Real 0m0. 000 s
User 0m0. 000 s
Sys 0m0. 000 s
#
#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 we will focus more on redirection-related content, so we will not analyze each example in detail. Note that the difference between time PWD 2> out.txt and (Time PWD) 2> out.txt is that stderrof PWD is redirected to out.txt, which is equivalent to the result of "time (PWD 2> out.txt.
Date command:
About the use of the date command, Baidu a lot, do not repeat, for example, can refer to: http://xingfujie.blog.51cto.com/2791569/637223
The following describes some common problems:
Question 1: % s and % N of date
There are many control formats in date, of which % s is to get the current time from 00:00:00 UTCTime Difference. Many other date formats control the output format of the current time. For example, only the time, minute, and second are output, and only the year, month, and day are output. % N is also the output format,% N outputs the nanosecond portion of the current time. Because date does not have millisecond-level output, the content below the second belongs to the nanosecond portion.. From this point of view, date can be very accurate and can reach the nanosecond level.
Question 2: Get a timestamp
Sometimes the timestamp, or random number, UUID, is also related to Baidu.Article(Such as searching for "shell date random number ). In general, you can use the combination of % s and % N. In the same second, % N will certainly not be the same for two running times, therefore, the combination of % s and % N can obtain a unique number.
[Plain] View plaincopyprint?
- # Date + % S. % N
- 1337435374.969263560
- # Date + % S + % N
- 1337435377 + 310281496
- # Date + % S _ % N
- 133743538213209334510
- # Date + % S _ % N
- 1337435383_169263078
- # Date + % S _ % N
- 1337435383_830009679
- #
#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 name a file with a unique identifier, and add a timestamp.
2. Linux Shell get time difference (use the date command)
As for the Time Command, the time difference is obtained, but obviously, time is only applicable to some simple situations, because the following parameters can be executed, sometimes you may need to execute multiple commands, so it is troublesome to use time.
(1)In seconds
Date gets the "current time". Obviously, a time difference can be obtained after two running dates. Theoretically, many formats can be used to represent the output of date to calculate the time difference. However, obviously, the most direct method is to use % s, so that a time difference can be calculated directly without complicated shell string processing. As follows:
[Plain] View plaincopyprint?
- # 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
#
Of course, this is tested in terminal, so it is good to use & to execute these commands continuously for writing a script in one line ....
[Plain] View plaincopyprint?
- 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)Unit: Ms
For more performance tests and other occasions, the time difference may be accurate to Ms. In fact, using date can reach Ms. Go directlyCodeRight.
[Plain] View plaincopyprint?
#! /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)
PS: This code is a simple test. You can get the LS command execution time. I believe the execution time is short enough. If you need to get the time difference below ms, I believe you won't use shell anymore. Hey hey, it's natural to rely on C.
The result is as follows:
[HTML] View plaincopyprint?
- #./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
#
I'm still satisfied. I can get this short time. Of course, theoretically, we can get the time difference in the unit of NS. However, I think it is accurate to use shell to get such a small time difference...
Note:
The idea of the above Code is actually very simple. % s is the number of seconds from the standard time, and % N is the part below the seconds of the current time. Obviously, % s and % N indicate the complete timestamp of the current time. The difference between the two timestamps is the time difference. The problem is how to solve the problem, probably using % s first. get the start and end time in % N format, and then use the cut command to get the ". "The part of the second and the part of the second (note: the insertion point between % s and % N is only used as a separator, and any possible characters are acceptable, as long as they can be separated by cut). Then, subtract the second part to get the second difference, and convert it to the millisecond difference. Then, calculate the difference (which may be negative) after converting the part of the nanoseconds to milliseconds. The sum of the two difference values is the real difference in milliseconds. It is easy to understand. The key is the use of cut. For Shell experts, there should be many methods to extract strings, but for non-shell experts like me, it is very difficult to write an extracted regular expression with awk or sed. Fortunately, we found the cut command and can easily extract this string. So: The method here is for reference only...
For "10 #" in the code, this indicates that the number following the code is a decimal number. This is required because the front of the nanoseconds is 0, shell seems to start with 0 and will be considered as octal by default, resulting in an error. In short, Baidu finds the cause and adds 10 # To all the numbers here #, indicates that all are in decimal format.