Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store a substring of the output of "time" function in bash script

So the built-in time function for bash should output in this format

real 0m0.002s
user 0m0.001s
sys  0m0.000s

I want to save the user time in milliseconds, like 001 what's a clean way to do this?

like image 271
Tony Stark Avatar asked Dec 16 '10 06:12

Tony Stark


People also ask

How do I store a string in a bash script?

Here, $var1 is used to store string value and $var2 is used to store a numeric value. Run the following commands from the terminal to combine two variables $var1 and $var2. Output: **Note: You can print the value of the variable without any quotation but if you use quotations then you have to use double quotations.

How do you store output in shell?

To store the output of a command in a variable, you can use the shell command substitution feature in the forms below: variable_name=$(command) variable_name=$(command [option ...] arg1 arg2 ...) OR variable_name='command' variable_name='command [option ...]


2 Answers

The clean way is to use the TIMEFORMAT shell variable to only print the user information. (man bash for more details.)

Then, of course you need to capture the output from it. This is impossible to do from the pipeline, as it's done internally by the shell, but you can run it in a subshell, and the output will go to standard error. But then you have to somehow redirect the output of the command elsewhere. Here, I just discard it, but many other possibilities exist, depending on exactly what you need to do. Then you need to munge d.ddd into dddd. Just deleting the period will do so.

(TIMEFORMAT="%U"; time ls > /dev/null) |& tr -d .

If you like, you can add | sed s/^0*// to eliminate the leading zeroes.

%R will give real time, %S system time. You can change the precision with e.g. %6U to get microseconds, though most systems won't be anywhere near that accurate.

man bash for help on redirections. man tr and man sed for help on how to use them.

like image 90
wnoise Avatar answered Oct 22 '22 19:10

wnoise


Bash's time builtin is a bit tricky to capture because it has special handling so that it can return the processing time for an entire pipeline like time ls -l | sort | uniq rather than just the processing time for only the ls -l command in my example.

The best way to capture just the output of time is the following redirection technique:

exec 3>&1 4>&2
foo=$( { time some_command 1>&3 2>&4; } 2>&1 ) # change some_command
exec 3>&- 4>&-

At this point if you were to echo "$foo" you would see something on the order of

real    0m0.013s
user    0m0.004s
sys     0m0.007s

Now to get just the 004 part of that you have quite a few options: sed, awk or straight bash to name the top 3. My personal favorite would be awk and it would look something like this:

foo=$({ time some_command 1>&3 2>&4;} 2>&1 | awk -F'[s.]' '/user/{print $3}')

Now if you were to echo "$foo" you would see just 004 as desired

like image 22
SiegeX Avatar answered Oct 22 '22 19:10

SiegeX