How to measure time of program execution and store that inside a variable Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) 2019 Community Moderator Election Results Why I closed the “Why is Kali so hard” questionForcing an 'added' alias to every commandBash time subtractionHow to report time and other information on all bash commands?How to measure rlogin time?Alias or Intercept complex bash command with argsWrite bash_history to a file with a timestampRedirecting standard error output to bash variableBash shell script program that prompts for and reads two integers from the user.bash history that stores execution time?How to time the execution of parallel commandsBash time keyword result only with second piped command, explain whyHow to capture stderr of a bash keyword (e.g. time)?
Is it fair for a professor to grade us on the possession of past papers?
How do I find out the mythology and history of my Fortress?
Maximum summed powersets with non-adjacent items
Amount of permutations on an NxNxN Rubik's Cube
Do square wave exist?
Fantasy story; one type of magic grows in power with use, but the more powerful they are, they more they are drawn to travel to their source
Extracting terms with certain heads in a function
Chinese Seal on silk painting - what does it mean?
When a candle burns, why does the top of wick glow if bottom of flame is hottest?
Why are there no cargo aircraft with "flying wing" design?
What are the out-of-universe reasons for the references to Toby Maguire-era Spider-Man in ITSV
2001: A Space Odyssey's use of the song "Daisy Bell" (Bicycle Built for Two); life imitates art or vice-versa?
Is "Reachable Object" really an NP-complete problem?
Around usage results
What's the meaning of "fortified infraction restraint"?
Is it a good idea to use CNN to classify 1D signal?
Should I use a zero-interest credit card for a large one-time purchase?
Can an alien society believe that their star system is the universe?
Most bit efficient text communication method?
Is it common practice to audition new musicians one-on-one before rehearsing with the entire band?
How to convince students of the implication truth values?
What causes the direction of lightning flashes?
Is grep documentation wrong?
old style "caution" boxes
How to measure time of program execution and store that inside a variable
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
2019 Community Moderator Election Results
Why I closed the “Why is Kali so hard” questionForcing an 'added' alias to every commandBash time subtractionHow to report time and other information on all bash commands?How to measure rlogin time?Alias or Intercept complex bash command with argsWrite bash_history to a file with a timestampRedirecting standard error output to bash variableBash shell script program that prompts for and reads two integers from the user.bash history that stores execution time?How to time the execution of parallel commandsBash time keyword result only with second piped command, explain whyHow to capture stderr of a bash keyword (e.g. time)?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
In order to find out how long certain operations within a Bash (v4+) script take, I would like to parse the output from the time
command "separately" and (ultimately) capture it within a Bash variable (let VARNAME=...
).
Now, I am using time -f '%e' ...
(or rather command time -f '%e' ...
because of the Bash built-in), but since I already redirect the output of the executed command I'm really lost as to how I would go about to capture the output of the time
command. Basically the problem here is to separate the output of time
from the output of the executed command(s).
What I want is the functionality of counting the amount of time in seconds (integers) between starting a command and its completion. It doesn't have to be the time
command or the respective built-in.
Edit: given the two useful answers below, I wanted to add two clarifications.
- I do not want to throw away the output of the executed command, but it will not really matter whether it ends up on stdout or stderr.
- I would prefer a direct approach over an indirect one (i.e. catching output directly as opposed to store it in intermediate files).
The solution using date
so far comes closes to what I want.
bash shell-script time
add a comment |
In order to find out how long certain operations within a Bash (v4+) script take, I would like to parse the output from the time
command "separately" and (ultimately) capture it within a Bash variable (let VARNAME=...
).
Now, I am using time -f '%e' ...
(or rather command time -f '%e' ...
because of the Bash built-in), but since I already redirect the output of the executed command I'm really lost as to how I would go about to capture the output of the time
command. Basically the problem here is to separate the output of time
from the output of the executed command(s).
What I want is the functionality of counting the amount of time in seconds (integers) between starting a command and its completion. It doesn't have to be the time
command or the respective built-in.
Edit: given the two useful answers below, I wanted to add two clarifications.
- I do not want to throw away the output of the executed command, but it will not really matter whether it ends up on stdout or stderr.
- I would prefer a direct approach over an indirect one (i.e. catching output directly as opposed to store it in intermediate files).
The solution using date
so far comes closes to what I want.
bash shell-script time
The most direct way to get the data and handle it while still letting it run normally would be to do it in a C program usingfork()
,execvp()
andwait3()/wait4()
. This is ultimately what time and friends are doing. I'm not aware of a simle way to do it in bash/perl without redirecting to a file or similar approach.
– penguin359
Apr 26 '11 at 22:20
There is a related question that you might find interesting going on here.
– Caleb
Apr 26 '11 at 23:09
@Caleb: thanks. Indeed interesting. However, for my purposes it's sufficient to do it in a script.
– 0xC0000022L
Apr 26 '11 at 23:28
add a comment |
In order to find out how long certain operations within a Bash (v4+) script take, I would like to parse the output from the time
command "separately" and (ultimately) capture it within a Bash variable (let VARNAME=...
).
Now, I am using time -f '%e' ...
(or rather command time -f '%e' ...
because of the Bash built-in), but since I already redirect the output of the executed command I'm really lost as to how I would go about to capture the output of the time
command. Basically the problem here is to separate the output of time
from the output of the executed command(s).
What I want is the functionality of counting the amount of time in seconds (integers) between starting a command and its completion. It doesn't have to be the time
command or the respective built-in.
Edit: given the two useful answers below, I wanted to add two clarifications.
- I do not want to throw away the output of the executed command, but it will not really matter whether it ends up on stdout or stderr.
- I would prefer a direct approach over an indirect one (i.e. catching output directly as opposed to store it in intermediate files).
The solution using date
so far comes closes to what I want.
bash shell-script time
In order to find out how long certain operations within a Bash (v4+) script take, I would like to parse the output from the time
command "separately" and (ultimately) capture it within a Bash variable (let VARNAME=...
).
Now, I am using time -f '%e' ...
(or rather command time -f '%e' ...
because of the Bash built-in), but since I already redirect the output of the executed command I'm really lost as to how I would go about to capture the output of the time
command. Basically the problem here is to separate the output of time
from the output of the executed command(s).
What I want is the functionality of counting the amount of time in seconds (integers) between starting a command and its completion. It doesn't have to be the time
command or the respective built-in.
Edit: given the two useful answers below, I wanted to add two clarifications.
- I do not want to throw away the output of the executed command, but it will not really matter whether it ends up on stdout or stderr.
- I would prefer a direct approach over an indirect one (i.e. catching output directly as opposed to store it in intermediate files).
The solution using date
so far comes closes to what I want.
bash shell-script time
bash shell-script time
edited Apr 26 '11 at 20:05
0xC0000022L
asked Apr 26 '11 at 19:17
0xC0000022L0xC0000022L
7,6131570125
7,6131570125
The most direct way to get the data and handle it while still letting it run normally would be to do it in a C program usingfork()
,execvp()
andwait3()/wait4()
. This is ultimately what time and friends are doing. I'm not aware of a simle way to do it in bash/perl without redirecting to a file or similar approach.
– penguin359
Apr 26 '11 at 22:20
There is a related question that you might find interesting going on here.
– Caleb
Apr 26 '11 at 23:09
@Caleb: thanks. Indeed interesting. However, for my purposes it's sufficient to do it in a script.
– 0xC0000022L
Apr 26 '11 at 23:28
add a comment |
The most direct way to get the data and handle it while still letting it run normally would be to do it in a C program usingfork()
,execvp()
andwait3()/wait4()
. This is ultimately what time and friends are doing. I'm not aware of a simle way to do it in bash/perl without redirecting to a file or similar approach.
– penguin359
Apr 26 '11 at 22:20
There is a related question that you might find interesting going on here.
– Caleb
Apr 26 '11 at 23:09
@Caleb: thanks. Indeed interesting. However, for my purposes it's sufficient to do it in a script.
– 0xC0000022L
Apr 26 '11 at 23:28
The most direct way to get the data and handle it while still letting it run normally would be to do it in a C program using
fork()
, execvp()
and wait3()/wait4()
. This is ultimately what time and friends are doing. I'm not aware of a simle way to do it in bash/perl without redirecting to a file or similar approach.– penguin359
Apr 26 '11 at 22:20
The most direct way to get the data and handle it while still letting it run normally would be to do it in a C program using
fork()
, execvp()
and wait3()/wait4()
. This is ultimately what time and friends are doing. I'm not aware of a simle way to do it in bash/perl without redirecting to a file or similar approach.– penguin359
Apr 26 '11 at 22:20
There is a related question that you might find interesting going on here.
– Caleb
Apr 26 '11 at 23:09
There is a related question that you might find interesting going on here.
– Caleb
Apr 26 '11 at 23:09
@Caleb: thanks. Indeed interesting. However, for my purposes it's sufficient to do it in a script.
– 0xC0000022L
Apr 26 '11 at 23:28
@Caleb: thanks. Indeed interesting. However, for my purposes it's sufficient to do it in a script.
– 0xC0000022L
Apr 26 '11 at 23:28
add a comment |
9 Answers
9
active
oldest
votes
To get the output of time
into a var use the following:
usr@srv $ mytime="$(time ( ls ) 2>&1 1>/dev/null )"
usr@srv $ echo "$mytime"
real 0m0.006s
user 0m0.001s
sys 0m0.005s
You can also just ask for a single time type, e.g. utime:
usr@srv $ utime="$( TIMEFORMAT='%lU';time ( ls ) 2>&1 1>/dev/null )"
usr@srv $ echo "$utime"
0m0.000s
To get the time you can also use date +%s.%N
, so take it before and after execution and calculate the diff:
START=$(date +%s.%N)
command
END=$(date +%s.%N)
DIFF=$(echo "$END - $START" | bc)
# echo $DIFF
4
I didn't want to throw away the output from the command though. So I guess your third code block is closest to what I had in mind. Although I'd write the last one asDIFF=$((END-START))
, making use of the arithmetic expressions. :) ... thanks for the answer. +1
– 0xC0000022L
Apr 26 '11 at 20:00
1
@STATUS_ACCESS_DENIED: Bash doesn't do floating point arithmetic, so if you want better than second resolution (.%N
in binfalse's code), you either needbc
or fancier calculations.
– Gilles
Apr 26 '11 at 21:11
@Gilles: I know. As I wrote in my question integers are fine. No need to have a higher resolution than second. But thanks, the date invocation would have to be changed. I had realized that, though.
– 0xC0000022L
Apr 26 '11 at 23:25
6
FYI, the date formatting %N doesn't seem to work on Mac OS X, it just returns "N". Ok on Ubuntu.
– David
Oct 19 '15 at 21:24
Note that while thetime (cmd) 2> something
works at redirecting the timing output tofile
, it's not meant to (as per documentation), doesn't in other shells wheretime
is a keyword and could be considered as a bug. I wouldn't rely on it as it may not work in future versions ofbash
.
– Stéphane Chazelas
Jan 29 '16 at 10:33
|
show 1 more comment
In bash, the output of the time
construct goes to its standard error, and you can redirect the standard error of the pipeline it affects. So let's start with a command that writes to its output and error streamas: sh -c 'echo out; echo 1>&2 err'
. In order not to mix up the command's error stream with the output from time
, we can temporarily divert the command's error stream to a different file descriptor:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3;
This writes out
to fd 1, err
to fd 3, and the times to fd 2:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3;
3> >(sed 's/^/ERR:/') 2> >(sed 's/^/TIME:/') > >(sed 's/^/OUT:/')
It would be more pleasant to have err
on fd 2 and the times on fd 3, so we swap them, which is cumbersome because there's no direct way to swap two file descriptors:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3; 3>&2 2>&4; 4>&3; 3> >(sed 's/^/TIME:/') 2> >(sed 's/^/ERR:/') > >(sed 's/^/OUT:/')
This shows how you can postprocess the output of the command, but if you want to capture both the output of the command and its times, you need to work harder. Using a temporary file is one solution. In fact, it's the only reliable solution if you need to capture both the command's standard error and its standard output. But otherwise, you can capture the whole output and take advantage of the fact that time
has a predictable format (if you use time -p
to get the POSIX format or the bash-specific TIMEFORMAT
variable).
nl=$'n'
output=$(TIMEFORMAT='%R %U %S %P'; mycommand)
set $output##*$nl; real_time=$1 user_time=$2 system_time=$3 cpu_percent=$4
output=$output%$nl*
If you only care about wall clock time, running date
before and after is a simple solution (if slightly more imprecise due to the extra time spent loading the external command).
Wow, a lot to test. Thanks a lot for the extensive reply. +1.
– 0xC0000022L
Apr 26 '11 at 23:25
add a comment |
With time, the command output comes out on stdout and the time comes out on stderr. So, to separate them, you can do:
command time -f '%e' [command] 1>[command output file] 2>[time output file]
But, now the time is in a file. I don't think Bash is able to put stderr in a variable directly. If you don't mind redirecting the command's output somewhere, you can do:
FOO=$((( command time -f '%e' [command]; ) 1>outputfile; ) 2>&1; )
When you do this, the command's output will be in outputfile
and the time it took to run will be in $FOO
.
1
ooh, I didn't realize. I knewtime
writes to stderr, but I didn't realize that it would merge stdout and stderr of the executed command into its stdout. But generally there is no direct method (i.e. without intermediate file)? +1.
– 0xC0000022L
Apr 26 '11 at 19:57
3
@STATUS_ACCESS_DENIED:time
does not merge its command'sstdout
andstderr
. The way I showed assumed that you only needed the command's stdout output. Sincebash
will only store what comes out ofstdout
, you have to redirect. In case you can safely drop your command's stderr: the time will always be on the last line of stderr. If you do need both your command's output streams, I'd suggest wrapping it in another script.
– marinus
Apr 26 '11 at 20:27
add a comment |
For that purpose it's probably better to use times
(than time
) in bash
which prints the accumulated user and system times for the shell and for processes run from the shell, example use:
$ (sleep 2; times) | (read tuser tsys; echo $tuser:$tsys)
0m0.001s:0m0.003s
See: help -m times
for more info.
add a comment |
In Putting all together previous responses, when in OSX
ProductName: Mac OS X
ProductVersion: 10.11.6
BuildVersion: 15G31+
you can do like
microtime()
python -c 'import time; print time.time()'
compute()
local START=$(microtime)
#$1 is command $2 are args
local END=$(microtime)
DIFF=$(echo "$END - $START"
add a comment |
If you are in bash
(and not sh
) and you DO NOT need sub-second accuracy, you can skip the call to date
entirely and do it without spawning any extra processes, without having to separate the combined output, and without having to capture and parse output from any commands:
# SECONDS is a bash special variable that returns the seconds since set.
SECONDS=0
mycmd <infile >outfile 2>errfile
DURATION_IN_SECONDS=$SECONDS
# Now `$DURATION_IN_SECONDS` is the number of seconds.
Nice. I have never heard of SECONDS before
– Bruno9779
Mar 22 '18 at 20:58
Do you happen to know starting with which Bash version this got introduced?
– 0xC0000022L
Mar 23 '18 at 13:30
add a comment |
Install /bin/time
(e.g. pacman -S time
)
So instead of error when trying -f
flag:
$ time -f %e sleep 0.5
bash: -f: command not found
real 0m0.001s
user 0m0.001s
sys 0m0.001s
You can actually use it:
$ /bin/time -f %e sleep 0.5
0.50
And get what you want - time in variable (example uses %e
for real elapsed time, for other options check man time
):
#!/bin/bash
tmpf="$(mktemp)"
/bin/time -f %e -o "$tmpf" sleep 0.5
variable="$(cat "$tmpf")"
rm "$tmpf"
echo "$variable"
/usr/bin/time
on many systems
– Basile Starynkevitch
Sep 19 '17 at 11:58
If you look closely I pointed that out in my question.time
is a shell builtin in Bash (and presumably other shells) but as long as the path to thetime
executable is inPATH
, we can usecommand time
to ensure we're running the external command as opposed to the builtin.
– 0xC0000022L
Sep 19 '17 at 12:34
add a comment |
Just as a heads up when working with the above statements and especially taking Grzegorz's answer in mind. I was surprised to see on my Ubuntu 16.04 Xenial system these two results:
$ which time
/usr/bin/time
$ time -f %e sleep 4
-f: command not found
real 0m0.071s
user 0m0.056s
sys 0m0.012s
$ /usr/bin/time -f %e sleep 4
4.00
I don't have any aliases set and so I don't know why this is happening.
1
time
is also a builtin shell.
– Basile Starynkevitch
Sep 19 '17 at 11:57
If you want to ensure you're running the command, usecommand
, if you want to ensure you're running the builtin, usebuiltin
. There's no magic here. Usehelp
to figure out the commands available ortype <command>
to figure out what type<command>
is (e.g. a builtin, external command, function or alias).
– 0xC0000022L
Sep 19 '17 at 12:29
Basile, you are quite right. I hadn't spotted the significance of thecommand
command. Which is fact ensures that /usr/bin/time is called. This means that the following two statements are compatible:$ command time -f %e sleep 4
and$ /usr/bin/time -f %e sleep
– Paul Pritchard
Sep 20 '17 at 6:38
add a comment |
try this, it runs a simple command with arguments and puts the times $real $user $sys and preserves the exit code.
It also does not fork subshells or trample on any variables except real user sys, and does not otherwise interfere with the running of the script
timer ()
time "$@" ; 2>$_ _>&- ; _>&2 2>"/tmp/$$.$BASHPID.$#FUNCNAME[@]"
set -- $?
read -d "" _ real _ user _ sys _ < "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
rm -f "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
return $1
e.g.
timer find /bin /sbin /usr rm /tmp/
echo $real $user $sys
note: it only times the simple command not a pipeline, whose components are run in a subshell
This version allows you to specify as $1 the name of the variables that should receive the 3 times:
timer ()
time "$@:4" ; 2>$_ _>&- ; _>&2 2>"/tmp/$$.$BASHPID.$#FUNCNAME[@]"
set -- $? "$@"
read -d "" _ "$2" _ "$3" _ "$4" _ < "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
rm -f "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
return $1
e.g.
timer r u s find /bin /sbin /usr rm /tmp/
echo $r $u $s
and may be useful if it ends up being called recursively, to avoid trampling on times; but then r u s etc should be declared local in their use.
http://blog.sam.liddicott.com/2016/01/timeing-bash-commands.html
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f12068%2fhow-to-measure-time-of-program-execution-and-store-that-inside-a-variable%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
9 Answers
9
active
oldest
votes
9 Answers
9
active
oldest
votes
active
oldest
votes
active
oldest
votes
To get the output of time
into a var use the following:
usr@srv $ mytime="$(time ( ls ) 2>&1 1>/dev/null )"
usr@srv $ echo "$mytime"
real 0m0.006s
user 0m0.001s
sys 0m0.005s
You can also just ask for a single time type, e.g. utime:
usr@srv $ utime="$( TIMEFORMAT='%lU';time ( ls ) 2>&1 1>/dev/null )"
usr@srv $ echo "$utime"
0m0.000s
To get the time you can also use date +%s.%N
, so take it before and after execution and calculate the diff:
START=$(date +%s.%N)
command
END=$(date +%s.%N)
DIFF=$(echo "$END - $START" | bc)
# echo $DIFF
4
I didn't want to throw away the output from the command though. So I guess your third code block is closest to what I had in mind. Although I'd write the last one asDIFF=$((END-START))
, making use of the arithmetic expressions. :) ... thanks for the answer. +1
– 0xC0000022L
Apr 26 '11 at 20:00
1
@STATUS_ACCESS_DENIED: Bash doesn't do floating point arithmetic, so if you want better than second resolution (.%N
in binfalse's code), you either needbc
or fancier calculations.
– Gilles
Apr 26 '11 at 21:11
@Gilles: I know. As I wrote in my question integers are fine. No need to have a higher resolution than second. But thanks, the date invocation would have to be changed. I had realized that, though.
– 0xC0000022L
Apr 26 '11 at 23:25
6
FYI, the date formatting %N doesn't seem to work on Mac OS X, it just returns "N". Ok on Ubuntu.
– David
Oct 19 '15 at 21:24
Note that while thetime (cmd) 2> something
works at redirecting the timing output tofile
, it's not meant to (as per documentation), doesn't in other shells wheretime
is a keyword and could be considered as a bug. I wouldn't rely on it as it may not work in future versions ofbash
.
– Stéphane Chazelas
Jan 29 '16 at 10:33
|
show 1 more comment
To get the output of time
into a var use the following:
usr@srv $ mytime="$(time ( ls ) 2>&1 1>/dev/null )"
usr@srv $ echo "$mytime"
real 0m0.006s
user 0m0.001s
sys 0m0.005s
You can also just ask for a single time type, e.g. utime:
usr@srv $ utime="$( TIMEFORMAT='%lU';time ( ls ) 2>&1 1>/dev/null )"
usr@srv $ echo "$utime"
0m0.000s
To get the time you can also use date +%s.%N
, so take it before and after execution and calculate the diff:
START=$(date +%s.%N)
command
END=$(date +%s.%N)
DIFF=$(echo "$END - $START" | bc)
# echo $DIFF
4
I didn't want to throw away the output from the command though. So I guess your third code block is closest to what I had in mind. Although I'd write the last one asDIFF=$((END-START))
, making use of the arithmetic expressions. :) ... thanks for the answer. +1
– 0xC0000022L
Apr 26 '11 at 20:00
1
@STATUS_ACCESS_DENIED: Bash doesn't do floating point arithmetic, so if you want better than second resolution (.%N
in binfalse's code), you either needbc
or fancier calculations.
– Gilles
Apr 26 '11 at 21:11
@Gilles: I know. As I wrote in my question integers are fine. No need to have a higher resolution than second. But thanks, the date invocation would have to be changed. I had realized that, though.
– 0xC0000022L
Apr 26 '11 at 23:25
6
FYI, the date formatting %N doesn't seem to work on Mac OS X, it just returns "N". Ok on Ubuntu.
– David
Oct 19 '15 at 21:24
Note that while thetime (cmd) 2> something
works at redirecting the timing output tofile
, it's not meant to (as per documentation), doesn't in other shells wheretime
is a keyword and could be considered as a bug. I wouldn't rely on it as it may not work in future versions ofbash
.
– Stéphane Chazelas
Jan 29 '16 at 10:33
|
show 1 more comment
To get the output of time
into a var use the following:
usr@srv $ mytime="$(time ( ls ) 2>&1 1>/dev/null )"
usr@srv $ echo "$mytime"
real 0m0.006s
user 0m0.001s
sys 0m0.005s
You can also just ask for a single time type, e.g. utime:
usr@srv $ utime="$( TIMEFORMAT='%lU';time ( ls ) 2>&1 1>/dev/null )"
usr@srv $ echo "$utime"
0m0.000s
To get the time you can also use date +%s.%N
, so take it before and after execution and calculate the diff:
START=$(date +%s.%N)
command
END=$(date +%s.%N)
DIFF=$(echo "$END - $START" | bc)
# echo $DIFF
To get the output of time
into a var use the following:
usr@srv $ mytime="$(time ( ls ) 2>&1 1>/dev/null )"
usr@srv $ echo "$mytime"
real 0m0.006s
user 0m0.001s
sys 0m0.005s
You can also just ask for a single time type, e.g. utime:
usr@srv $ utime="$( TIMEFORMAT='%lU';time ( ls ) 2>&1 1>/dev/null )"
usr@srv $ echo "$utime"
0m0.000s
To get the time you can also use date +%s.%N
, so take it before and after execution and calculate the diff:
START=$(date +%s.%N)
command
END=$(date +%s.%N)
DIFF=$(echo "$END - $START" | bc)
# echo $DIFF
edited 10 hours ago
Rui F Ribeiro
42.1k1484142
42.1k1484142
answered Apr 26 '11 at 19:33
binfalsebinfalse
3,47311727
3,47311727
4
I didn't want to throw away the output from the command though. So I guess your third code block is closest to what I had in mind. Although I'd write the last one asDIFF=$((END-START))
, making use of the arithmetic expressions. :) ... thanks for the answer. +1
– 0xC0000022L
Apr 26 '11 at 20:00
1
@STATUS_ACCESS_DENIED: Bash doesn't do floating point arithmetic, so if you want better than second resolution (.%N
in binfalse's code), you either needbc
or fancier calculations.
– Gilles
Apr 26 '11 at 21:11
@Gilles: I know. As I wrote in my question integers are fine. No need to have a higher resolution than second. But thanks, the date invocation would have to be changed. I had realized that, though.
– 0xC0000022L
Apr 26 '11 at 23:25
6
FYI, the date formatting %N doesn't seem to work on Mac OS X, it just returns "N". Ok on Ubuntu.
– David
Oct 19 '15 at 21:24
Note that while thetime (cmd) 2> something
works at redirecting the timing output tofile
, it's not meant to (as per documentation), doesn't in other shells wheretime
is a keyword and could be considered as a bug. I wouldn't rely on it as it may not work in future versions ofbash
.
– Stéphane Chazelas
Jan 29 '16 at 10:33
|
show 1 more comment
4
I didn't want to throw away the output from the command though. So I guess your third code block is closest to what I had in mind. Although I'd write the last one asDIFF=$((END-START))
, making use of the arithmetic expressions. :) ... thanks for the answer. +1
– 0xC0000022L
Apr 26 '11 at 20:00
1
@STATUS_ACCESS_DENIED: Bash doesn't do floating point arithmetic, so if you want better than second resolution (.%N
in binfalse's code), you either needbc
or fancier calculations.
– Gilles
Apr 26 '11 at 21:11
@Gilles: I know. As I wrote in my question integers are fine. No need to have a higher resolution than second. But thanks, the date invocation would have to be changed. I had realized that, though.
– 0xC0000022L
Apr 26 '11 at 23:25
6
FYI, the date formatting %N doesn't seem to work on Mac OS X, it just returns "N". Ok on Ubuntu.
– David
Oct 19 '15 at 21:24
Note that while thetime (cmd) 2> something
works at redirecting the timing output tofile
, it's not meant to (as per documentation), doesn't in other shells wheretime
is a keyword and could be considered as a bug. I wouldn't rely on it as it may not work in future versions ofbash
.
– Stéphane Chazelas
Jan 29 '16 at 10:33
4
4
I didn't want to throw away the output from the command though. So I guess your third code block is closest to what I had in mind. Although I'd write the last one as
DIFF=$((END-START))
, making use of the arithmetic expressions. :) ... thanks for the answer. +1– 0xC0000022L
Apr 26 '11 at 20:00
I didn't want to throw away the output from the command though. So I guess your third code block is closest to what I had in mind. Although I'd write the last one as
DIFF=$((END-START))
, making use of the arithmetic expressions. :) ... thanks for the answer. +1– 0xC0000022L
Apr 26 '11 at 20:00
1
1
@STATUS_ACCESS_DENIED: Bash doesn't do floating point arithmetic, so if you want better than second resolution (
.%N
in binfalse's code), you either need bc
or fancier calculations.– Gilles
Apr 26 '11 at 21:11
@STATUS_ACCESS_DENIED: Bash doesn't do floating point arithmetic, so if you want better than second resolution (
.%N
in binfalse's code), you either need bc
or fancier calculations.– Gilles
Apr 26 '11 at 21:11
@Gilles: I know. As I wrote in my question integers are fine. No need to have a higher resolution than second. But thanks, the date invocation would have to be changed. I had realized that, though.
– 0xC0000022L
Apr 26 '11 at 23:25
@Gilles: I know. As I wrote in my question integers are fine. No need to have a higher resolution than second. But thanks, the date invocation would have to be changed. I had realized that, though.
– 0xC0000022L
Apr 26 '11 at 23:25
6
6
FYI, the date formatting %N doesn't seem to work on Mac OS X, it just returns "N". Ok on Ubuntu.
– David
Oct 19 '15 at 21:24
FYI, the date formatting %N doesn't seem to work on Mac OS X, it just returns "N". Ok on Ubuntu.
– David
Oct 19 '15 at 21:24
Note that while the
time (cmd) 2> something
works at redirecting the timing output to file
, it's not meant to (as per documentation), doesn't in other shells where time
is a keyword and could be considered as a bug. I wouldn't rely on it as it may not work in future versions of bash
.– Stéphane Chazelas
Jan 29 '16 at 10:33
Note that while the
time (cmd) 2> something
works at redirecting the timing output to file
, it's not meant to (as per documentation), doesn't in other shells where time
is a keyword and could be considered as a bug. I wouldn't rely on it as it may not work in future versions of bash
.– Stéphane Chazelas
Jan 29 '16 at 10:33
|
show 1 more comment
In bash, the output of the time
construct goes to its standard error, and you can redirect the standard error of the pipeline it affects. So let's start with a command that writes to its output and error streamas: sh -c 'echo out; echo 1>&2 err'
. In order not to mix up the command's error stream with the output from time
, we can temporarily divert the command's error stream to a different file descriptor:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3;
This writes out
to fd 1, err
to fd 3, and the times to fd 2:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3;
3> >(sed 's/^/ERR:/') 2> >(sed 's/^/TIME:/') > >(sed 's/^/OUT:/')
It would be more pleasant to have err
on fd 2 and the times on fd 3, so we swap them, which is cumbersome because there's no direct way to swap two file descriptors:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3; 3>&2 2>&4; 4>&3; 3> >(sed 's/^/TIME:/') 2> >(sed 's/^/ERR:/') > >(sed 's/^/OUT:/')
This shows how you can postprocess the output of the command, but if you want to capture both the output of the command and its times, you need to work harder. Using a temporary file is one solution. In fact, it's the only reliable solution if you need to capture both the command's standard error and its standard output. But otherwise, you can capture the whole output and take advantage of the fact that time
has a predictable format (if you use time -p
to get the POSIX format or the bash-specific TIMEFORMAT
variable).
nl=$'n'
output=$(TIMEFORMAT='%R %U %S %P'; mycommand)
set $output##*$nl; real_time=$1 user_time=$2 system_time=$3 cpu_percent=$4
output=$output%$nl*
If you only care about wall clock time, running date
before and after is a simple solution (if slightly more imprecise due to the extra time spent loading the external command).
Wow, a lot to test. Thanks a lot for the extensive reply. +1.
– 0xC0000022L
Apr 26 '11 at 23:25
add a comment |
In bash, the output of the time
construct goes to its standard error, and you can redirect the standard error of the pipeline it affects. So let's start with a command that writes to its output and error streamas: sh -c 'echo out; echo 1>&2 err'
. In order not to mix up the command's error stream with the output from time
, we can temporarily divert the command's error stream to a different file descriptor:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3;
This writes out
to fd 1, err
to fd 3, and the times to fd 2:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3;
3> >(sed 's/^/ERR:/') 2> >(sed 's/^/TIME:/') > >(sed 's/^/OUT:/')
It would be more pleasant to have err
on fd 2 and the times on fd 3, so we swap them, which is cumbersome because there's no direct way to swap two file descriptors:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3; 3>&2 2>&4; 4>&3; 3> >(sed 's/^/TIME:/') 2> >(sed 's/^/ERR:/') > >(sed 's/^/OUT:/')
This shows how you can postprocess the output of the command, but if you want to capture both the output of the command and its times, you need to work harder. Using a temporary file is one solution. In fact, it's the only reliable solution if you need to capture both the command's standard error and its standard output. But otherwise, you can capture the whole output and take advantage of the fact that time
has a predictable format (if you use time -p
to get the POSIX format or the bash-specific TIMEFORMAT
variable).
nl=$'n'
output=$(TIMEFORMAT='%R %U %S %P'; mycommand)
set $output##*$nl; real_time=$1 user_time=$2 system_time=$3 cpu_percent=$4
output=$output%$nl*
If you only care about wall clock time, running date
before and after is a simple solution (if slightly more imprecise due to the extra time spent loading the external command).
Wow, a lot to test. Thanks a lot for the extensive reply. +1.
– 0xC0000022L
Apr 26 '11 at 23:25
add a comment |
In bash, the output of the time
construct goes to its standard error, and you can redirect the standard error of the pipeline it affects. So let's start with a command that writes to its output and error streamas: sh -c 'echo out; echo 1>&2 err'
. In order not to mix up the command's error stream with the output from time
, we can temporarily divert the command's error stream to a different file descriptor:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3;
This writes out
to fd 1, err
to fd 3, and the times to fd 2:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3;
3> >(sed 's/^/ERR:/') 2> >(sed 's/^/TIME:/') > >(sed 's/^/OUT:/')
It would be more pleasant to have err
on fd 2 and the times on fd 3, so we swap them, which is cumbersome because there's no direct way to swap two file descriptors:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3; 3>&2 2>&4; 4>&3; 3> >(sed 's/^/TIME:/') 2> >(sed 's/^/ERR:/') > >(sed 's/^/OUT:/')
This shows how you can postprocess the output of the command, but if you want to capture both the output of the command and its times, you need to work harder. Using a temporary file is one solution. In fact, it's the only reliable solution if you need to capture both the command's standard error and its standard output. But otherwise, you can capture the whole output and take advantage of the fact that time
has a predictable format (if you use time -p
to get the POSIX format or the bash-specific TIMEFORMAT
variable).
nl=$'n'
output=$(TIMEFORMAT='%R %U %S %P'; mycommand)
set $output##*$nl; real_time=$1 user_time=$2 system_time=$3 cpu_percent=$4
output=$output%$nl*
If you only care about wall clock time, running date
before and after is a simple solution (if slightly more imprecise due to the extra time spent loading the external command).
In bash, the output of the time
construct goes to its standard error, and you can redirect the standard error of the pipeline it affects. So let's start with a command that writes to its output and error streamas: sh -c 'echo out; echo 1>&2 err'
. In order not to mix up the command's error stream with the output from time
, we can temporarily divert the command's error stream to a different file descriptor:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3;
This writes out
to fd 1, err
to fd 3, and the times to fd 2:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3;
3> >(sed 's/^/ERR:/') 2> >(sed 's/^/TIME:/') > >(sed 's/^/OUT:/')
It would be more pleasant to have err
on fd 2 and the times on fd 3, so we swap them, which is cumbersome because there's no direct way to swap two file descriptors:
time -p sh -c 'echo out; echo 1>&2 err' 2>&3; 3>&2 2>&4; 4>&3; 3> >(sed 's/^/TIME:/') 2> >(sed 's/^/ERR:/') > >(sed 's/^/OUT:/')
This shows how you can postprocess the output of the command, but if you want to capture both the output of the command and its times, you need to work harder. Using a temporary file is one solution. In fact, it's the only reliable solution if you need to capture both the command's standard error and its standard output. But otherwise, you can capture the whole output and take advantage of the fact that time
has a predictable format (if you use time -p
to get the POSIX format or the bash-specific TIMEFORMAT
variable).
nl=$'n'
output=$(TIMEFORMAT='%R %U %S %P'; mycommand)
set $output##*$nl; real_time=$1 user_time=$2 system_time=$3 cpu_percent=$4
output=$output%$nl*
If you only care about wall clock time, running date
before and after is a simple solution (if slightly more imprecise due to the extra time spent loading the external command).
answered Apr 26 '11 at 21:10
GillesGilles
548k13011151631
548k13011151631
Wow, a lot to test. Thanks a lot for the extensive reply. +1.
– 0xC0000022L
Apr 26 '11 at 23:25
add a comment |
Wow, a lot to test. Thanks a lot for the extensive reply. +1.
– 0xC0000022L
Apr 26 '11 at 23:25
Wow, a lot to test. Thanks a lot for the extensive reply. +1.
– 0xC0000022L
Apr 26 '11 at 23:25
Wow, a lot to test. Thanks a lot for the extensive reply. +1.
– 0xC0000022L
Apr 26 '11 at 23:25
add a comment |
With time, the command output comes out on stdout and the time comes out on stderr. So, to separate them, you can do:
command time -f '%e' [command] 1>[command output file] 2>[time output file]
But, now the time is in a file. I don't think Bash is able to put stderr in a variable directly. If you don't mind redirecting the command's output somewhere, you can do:
FOO=$((( command time -f '%e' [command]; ) 1>outputfile; ) 2>&1; )
When you do this, the command's output will be in outputfile
and the time it took to run will be in $FOO
.
1
ooh, I didn't realize. I knewtime
writes to stderr, but I didn't realize that it would merge stdout and stderr of the executed command into its stdout. But generally there is no direct method (i.e. without intermediate file)? +1.
– 0xC0000022L
Apr 26 '11 at 19:57
3
@STATUS_ACCESS_DENIED:time
does not merge its command'sstdout
andstderr
. The way I showed assumed that you only needed the command's stdout output. Sincebash
will only store what comes out ofstdout
, you have to redirect. In case you can safely drop your command's stderr: the time will always be on the last line of stderr. If you do need both your command's output streams, I'd suggest wrapping it in another script.
– marinus
Apr 26 '11 at 20:27
add a comment |
With time, the command output comes out on stdout and the time comes out on stderr. So, to separate them, you can do:
command time -f '%e' [command] 1>[command output file] 2>[time output file]
But, now the time is in a file. I don't think Bash is able to put stderr in a variable directly. If you don't mind redirecting the command's output somewhere, you can do:
FOO=$((( command time -f '%e' [command]; ) 1>outputfile; ) 2>&1; )
When you do this, the command's output will be in outputfile
and the time it took to run will be in $FOO
.
1
ooh, I didn't realize. I knewtime
writes to stderr, but I didn't realize that it would merge stdout and stderr of the executed command into its stdout. But generally there is no direct method (i.e. without intermediate file)? +1.
– 0xC0000022L
Apr 26 '11 at 19:57
3
@STATUS_ACCESS_DENIED:time
does not merge its command'sstdout
andstderr
. The way I showed assumed that you only needed the command's stdout output. Sincebash
will only store what comes out ofstdout
, you have to redirect. In case you can safely drop your command's stderr: the time will always be on the last line of stderr. If you do need both your command's output streams, I'd suggest wrapping it in another script.
– marinus
Apr 26 '11 at 20:27
add a comment |
With time, the command output comes out on stdout and the time comes out on stderr. So, to separate them, you can do:
command time -f '%e' [command] 1>[command output file] 2>[time output file]
But, now the time is in a file. I don't think Bash is able to put stderr in a variable directly. If you don't mind redirecting the command's output somewhere, you can do:
FOO=$((( command time -f '%e' [command]; ) 1>outputfile; ) 2>&1; )
When you do this, the command's output will be in outputfile
and the time it took to run will be in $FOO
.
With time, the command output comes out on stdout and the time comes out on stderr. So, to separate them, you can do:
command time -f '%e' [command] 1>[command output file] 2>[time output file]
But, now the time is in a file. I don't think Bash is able to put stderr in a variable directly. If you don't mind redirecting the command's output somewhere, you can do:
FOO=$((( command time -f '%e' [command]; ) 1>outputfile; ) 2>&1; )
When you do this, the command's output will be in outputfile
and the time it took to run will be in $FOO
.
answered Apr 26 '11 at 19:43
marinusmarinus
1,6761110
1,6761110
1
ooh, I didn't realize. I knewtime
writes to stderr, but I didn't realize that it would merge stdout and stderr of the executed command into its stdout. But generally there is no direct method (i.e. without intermediate file)? +1.
– 0xC0000022L
Apr 26 '11 at 19:57
3
@STATUS_ACCESS_DENIED:time
does not merge its command'sstdout
andstderr
. The way I showed assumed that you only needed the command's stdout output. Sincebash
will only store what comes out ofstdout
, you have to redirect. In case you can safely drop your command's stderr: the time will always be on the last line of stderr. If you do need both your command's output streams, I'd suggest wrapping it in another script.
– marinus
Apr 26 '11 at 20:27
add a comment |
1
ooh, I didn't realize. I knewtime
writes to stderr, but I didn't realize that it would merge stdout and stderr of the executed command into its stdout. But generally there is no direct method (i.e. without intermediate file)? +1.
– 0xC0000022L
Apr 26 '11 at 19:57
3
@STATUS_ACCESS_DENIED:time
does not merge its command'sstdout
andstderr
. The way I showed assumed that you only needed the command's stdout output. Sincebash
will only store what comes out ofstdout
, you have to redirect. In case you can safely drop your command's stderr: the time will always be on the last line of stderr. If you do need both your command's output streams, I'd suggest wrapping it in another script.
– marinus
Apr 26 '11 at 20:27
1
1
ooh, I didn't realize. I knew
time
writes to stderr, but I didn't realize that it would merge stdout and stderr of the executed command into its stdout. But generally there is no direct method (i.e. without intermediate file)? +1.– 0xC0000022L
Apr 26 '11 at 19:57
ooh, I didn't realize. I knew
time
writes to stderr, but I didn't realize that it would merge stdout and stderr of the executed command into its stdout. But generally there is no direct method (i.e. without intermediate file)? +1.– 0xC0000022L
Apr 26 '11 at 19:57
3
3
@STATUS_ACCESS_DENIED:
time
does not merge its command's stdout
and stderr
. The way I showed assumed that you only needed the command's stdout output. Since bash
will only store what comes out of stdout
, you have to redirect. In case you can safely drop your command's stderr: the time will always be on the last line of stderr. If you do need both your command's output streams, I'd suggest wrapping it in another script.– marinus
Apr 26 '11 at 20:27
@STATUS_ACCESS_DENIED:
time
does not merge its command's stdout
and stderr
. The way I showed assumed that you only needed the command's stdout output. Since bash
will only store what comes out of stdout
, you have to redirect. In case you can safely drop your command's stderr: the time will always be on the last line of stderr. If you do need both your command's output streams, I'd suggest wrapping it in another script.– marinus
Apr 26 '11 at 20:27
add a comment |
For that purpose it's probably better to use times
(than time
) in bash
which prints the accumulated user and system times for the shell and for processes run from the shell, example use:
$ (sleep 2; times) | (read tuser tsys; echo $tuser:$tsys)
0m0.001s:0m0.003s
See: help -m times
for more info.
add a comment |
For that purpose it's probably better to use times
(than time
) in bash
which prints the accumulated user and system times for the shell and for processes run from the shell, example use:
$ (sleep 2; times) | (read tuser tsys; echo $tuser:$tsys)
0m0.001s:0m0.003s
See: help -m times
for more info.
add a comment |
For that purpose it's probably better to use times
(than time
) in bash
which prints the accumulated user and system times for the shell and for processes run from the shell, example use:
$ (sleep 2; times) | (read tuser tsys; echo $tuser:$tsys)
0m0.001s:0m0.003s
See: help -m times
for more info.
For that purpose it's probably better to use times
(than time
) in bash
which prints the accumulated user and system times for the shell and for processes run from the shell, example use:
$ (sleep 2; times) | (read tuser tsys; echo $tuser:$tsys)
0m0.001s:0m0.003s
See: help -m times
for more info.
answered Jan 17 '16 at 14:57
kenorbkenorb
9,111374112
9,111374112
add a comment |
add a comment |
In Putting all together previous responses, when in OSX
ProductName: Mac OS X
ProductVersion: 10.11.6
BuildVersion: 15G31+
you can do like
microtime()
python -c 'import time; print time.time()'
compute()
local START=$(microtime)
#$1 is command $2 are args
local END=$(microtime)
DIFF=$(echo "$END - $START"
add a comment |
In Putting all together previous responses, when in OSX
ProductName: Mac OS X
ProductVersion: 10.11.6
BuildVersion: 15G31+
you can do like
microtime()
python -c 'import time; print time.time()'
compute()
local START=$(microtime)
#$1 is command $2 are args
local END=$(microtime)
DIFF=$(echo "$END - $START"
add a comment |
In Putting all together previous responses, when in OSX
ProductName: Mac OS X
ProductVersion: 10.11.6
BuildVersion: 15G31+
you can do like
microtime()
python -c 'import time; print time.time()'
compute()
local START=$(microtime)
#$1 is command $2 are args
local END=$(microtime)
DIFF=$(echo "$END - $START"
In Putting all together previous responses, when in OSX
ProductName: Mac OS X
ProductVersion: 10.11.6
BuildVersion: 15G31+
you can do like
microtime()
python -c 'import time; print time.time()'
compute()
local START=$(microtime)
#$1 is command $2 are args
local END=$(microtime)
DIFF=$(echo "$END - $START"
answered Aug 1 '16 at 13:46
loretoparisiloretoparisi
190213
190213
add a comment |
add a comment |
If you are in bash
(and not sh
) and you DO NOT need sub-second accuracy, you can skip the call to date
entirely and do it without spawning any extra processes, without having to separate the combined output, and without having to capture and parse output from any commands:
# SECONDS is a bash special variable that returns the seconds since set.
SECONDS=0
mycmd <infile >outfile 2>errfile
DURATION_IN_SECONDS=$SECONDS
# Now `$DURATION_IN_SECONDS` is the number of seconds.
Nice. I have never heard of SECONDS before
– Bruno9779
Mar 22 '18 at 20:58
Do you happen to know starting with which Bash version this got introduced?
– 0xC0000022L
Mar 23 '18 at 13:30
add a comment |
If you are in bash
(and not sh
) and you DO NOT need sub-second accuracy, you can skip the call to date
entirely and do it without spawning any extra processes, without having to separate the combined output, and without having to capture and parse output from any commands:
# SECONDS is a bash special variable that returns the seconds since set.
SECONDS=0
mycmd <infile >outfile 2>errfile
DURATION_IN_SECONDS=$SECONDS
# Now `$DURATION_IN_SECONDS` is the number of seconds.
Nice. I have never heard of SECONDS before
– Bruno9779
Mar 22 '18 at 20:58
Do you happen to know starting with which Bash version this got introduced?
– 0xC0000022L
Mar 23 '18 at 13:30
add a comment |
If you are in bash
(and not sh
) and you DO NOT need sub-second accuracy, you can skip the call to date
entirely and do it without spawning any extra processes, without having to separate the combined output, and without having to capture and parse output from any commands:
# SECONDS is a bash special variable that returns the seconds since set.
SECONDS=0
mycmd <infile >outfile 2>errfile
DURATION_IN_SECONDS=$SECONDS
# Now `$DURATION_IN_SECONDS` is the number of seconds.
If you are in bash
(and not sh
) and you DO NOT need sub-second accuracy, you can skip the call to date
entirely and do it without spawning any extra processes, without having to separate the combined output, and without having to capture and parse output from any commands:
# SECONDS is a bash special variable that returns the seconds since set.
SECONDS=0
mycmd <infile >outfile 2>errfile
DURATION_IN_SECONDS=$SECONDS
# Now `$DURATION_IN_SECONDS` is the number of seconds.
answered Mar 22 '18 at 20:41
sanpathsanpath
411
411
Nice. I have never heard of SECONDS before
– Bruno9779
Mar 22 '18 at 20:58
Do you happen to know starting with which Bash version this got introduced?
– 0xC0000022L
Mar 23 '18 at 13:30
add a comment |
Nice. I have never heard of SECONDS before
– Bruno9779
Mar 22 '18 at 20:58
Do you happen to know starting with which Bash version this got introduced?
– 0xC0000022L
Mar 23 '18 at 13:30
Nice. I have never heard of SECONDS before
– Bruno9779
Mar 22 '18 at 20:58
Nice. I have never heard of SECONDS before
– Bruno9779
Mar 22 '18 at 20:58
Do you happen to know starting with which Bash version this got introduced?
– 0xC0000022L
Mar 23 '18 at 13:30
Do you happen to know starting with which Bash version this got introduced?
– 0xC0000022L
Mar 23 '18 at 13:30
add a comment |
Install /bin/time
(e.g. pacman -S time
)
So instead of error when trying -f
flag:
$ time -f %e sleep 0.5
bash: -f: command not found
real 0m0.001s
user 0m0.001s
sys 0m0.001s
You can actually use it:
$ /bin/time -f %e sleep 0.5
0.50
And get what you want - time in variable (example uses %e
for real elapsed time, for other options check man time
):
#!/bin/bash
tmpf="$(mktemp)"
/bin/time -f %e -o "$tmpf" sleep 0.5
variable="$(cat "$tmpf")"
rm "$tmpf"
echo "$variable"
/usr/bin/time
on many systems
– Basile Starynkevitch
Sep 19 '17 at 11:58
If you look closely I pointed that out in my question.time
is a shell builtin in Bash (and presumably other shells) but as long as the path to thetime
executable is inPATH
, we can usecommand time
to ensure we're running the external command as opposed to the builtin.
– 0xC0000022L
Sep 19 '17 at 12:34
add a comment |
Install /bin/time
(e.g. pacman -S time
)
So instead of error when trying -f
flag:
$ time -f %e sleep 0.5
bash: -f: command not found
real 0m0.001s
user 0m0.001s
sys 0m0.001s
You can actually use it:
$ /bin/time -f %e sleep 0.5
0.50
And get what you want - time in variable (example uses %e
for real elapsed time, for other options check man time
):
#!/bin/bash
tmpf="$(mktemp)"
/bin/time -f %e -o "$tmpf" sleep 0.5
variable="$(cat "$tmpf")"
rm "$tmpf"
echo "$variable"
/usr/bin/time
on many systems
– Basile Starynkevitch
Sep 19 '17 at 11:58
If you look closely I pointed that out in my question.time
is a shell builtin in Bash (and presumably other shells) but as long as the path to thetime
executable is inPATH
, we can usecommand time
to ensure we're running the external command as opposed to the builtin.
– 0xC0000022L
Sep 19 '17 at 12:34
add a comment |
Install /bin/time
(e.g. pacman -S time
)
So instead of error when trying -f
flag:
$ time -f %e sleep 0.5
bash: -f: command not found
real 0m0.001s
user 0m0.001s
sys 0m0.001s
You can actually use it:
$ /bin/time -f %e sleep 0.5
0.50
And get what you want - time in variable (example uses %e
for real elapsed time, for other options check man time
):
#!/bin/bash
tmpf="$(mktemp)"
/bin/time -f %e -o "$tmpf" sleep 0.5
variable="$(cat "$tmpf")"
rm "$tmpf"
echo "$variable"
Install /bin/time
(e.g. pacman -S time
)
So instead of error when trying -f
flag:
$ time -f %e sleep 0.5
bash: -f: command not found
real 0m0.001s
user 0m0.001s
sys 0m0.001s
You can actually use it:
$ /bin/time -f %e sleep 0.5
0.50
And get what you want - time in variable (example uses %e
for real elapsed time, for other options check man time
):
#!/bin/bash
tmpf="$(mktemp)"
/bin/time -f %e -o "$tmpf" sleep 0.5
variable="$(cat "$tmpf")"
rm "$tmpf"
echo "$variable"
answered Jul 29 '17 at 12:04
Grzegorz WierzowieckiGrzegorz Wierzowiecki
5,4171564107
5,4171564107
/usr/bin/time
on many systems
– Basile Starynkevitch
Sep 19 '17 at 11:58
If you look closely I pointed that out in my question.time
is a shell builtin in Bash (and presumably other shells) but as long as the path to thetime
executable is inPATH
, we can usecommand time
to ensure we're running the external command as opposed to the builtin.
– 0xC0000022L
Sep 19 '17 at 12:34
add a comment |
/usr/bin/time
on many systems
– Basile Starynkevitch
Sep 19 '17 at 11:58
If you look closely I pointed that out in my question.time
is a shell builtin in Bash (and presumably other shells) but as long as the path to thetime
executable is inPATH
, we can usecommand time
to ensure we're running the external command as opposed to the builtin.
– 0xC0000022L
Sep 19 '17 at 12:34
/usr/bin/time
on many systems– Basile Starynkevitch
Sep 19 '17 at 11:58
/usr/bin/time
on many systems– Basile Starynkevitch
Sep 19 '17 at 11:58
If you look closely I pointed that out in my question.
time
is a shell builtin in Bash (and presumably other shells) but as long as the path to the time
executable is in PATH
, we can use command time
to ensure we're running the external command as opposed to the builtin.– 0xC0000022L
Sep 19 '17 at 12:34
If you look closely I pointed that out in my question.
time
is a shell builtin in Bash (and presumably other shells) but as long as the path to the time
executable is in PATH
, we can use command time
to ensure we're running the external command as opposed to the builtin.– 0xC0000022L
Sep 19 '17 at 12:34
add a comment |
Just as a heads up when working with the above statements and especially taking Grzegorz's answer in mind. I was surprised to see on my Ubuntu 16.04 Xenial system these two results:
$ which time
/usr/bin/time
$ time -f %e sleep 4
-f: command not found
real 0m0.071s
user 0m0.056s
sys 0m0.012s
$ /usr/bin/time -f %e sleep 4
4.00
I don't have any aliases set and so I don't know why this is happening.
1
time
is also a builtin shell.
– Basile Starynkevitch
Sep 19 '17 at 11:57
If you want to ensure you're running the command, usecommand
, if you want to ensure you're running the builtin, usebuiltin
. There's no magic here. Usehelp
to figure out the commands available ortype <command>
to figure out what type<command>
is (e.g. a builtin, external command, function or alias).
– 0xC0000022L
Sep 19 '17 at 12:29
Basile, you are quite right. I hadn't spotted the significance of thecommand
command. Which is fact ensures that /usr/bin/time is called. This means that the following two statements are compatible:$ command time -f %e sleep 4
and$ /usr/bin/time -f %e sleep
– Paul Pritchard
Sep 20 '17 at 6:38
add a comment |
Just as a heads up when working with the above statements and especially taking Grzegorz's answer in mind. I was surprised to see on my Ubuntu 16.04 Xenial system these two results:
$ which time
/usr/bin/time
$ time -f %e sleep 4
-f: command not found
real 0m0.071s
user 0m0.056s
sys 0m0.012s
$ /usr/bin/time -f %e sleep 4
4.00
I don't have any aliases set and so I don't know why this is happening.
1
time
is also a builtin shell.
– Basile Starynkevitch
Sep 19 '17 at 11:57
If you want to ensure you're running the command, usecommand
, if you want to ensure you're running the builtin, usebuiltin
. There's no magic here. Usehelp
to figure out the commands available ortype <command>
to figure out what type<command>
is (e.g. a builtin, external command, function or alias).
– 0xC0000022L
Sep 19 '17 at 12:29
Basile, you are quite right. I hadn't spotted the significance of thecommand
command. Which is fact ensures that /usr/bin/time is called. This means that the following two statements are compatible:$ command time -f %e sleep 4
and$ /usr/bin/time -f %e sleep
– Paul Pritchard
Sep 20 '17 at 6:38
add a comment |
Just as a heads up when working with the above statements and especially taking Grzegorz's answer in mind. I was surprised to see on my Ubuntu 16.04 Xenial system these two results:
$ which time
/usr/bin/time
$ time -f %e sleep 4
-f: command not found
real 0m0.071s
user 0m0.056s
sys 0m0.012s
$ /usr/bin/time -f %e sleep 4
4.00
I don't have any aliases set and so I don't know why this is happening.
Just as a heads up when working with the above statements and especially taking Grzegorz's answer in mind. I was surprised to see on my Ubuntu 16.04 Xenial system these two results:
$ which time
/usr/bin/time
$ time -f %e sleep 4
-f: command not found
real 0m0.071s
user 0m0.056s
sys 0m0.012s
$ /usr/bin/time -f %e sleep 4
4.00
I don't have any aliases set and so I don't know why this is happening.
answered Sep 19 '17 at 11:22
Paul PritchardPaul Pritchard
112
112
1
time
is also a builtin shell.
– Basile Starynkevitch
Sep 19 '17 at 11:57
If you want to ensure you're running the command, usecommand
, if you want to ensure you're running the builtin, usebuiltin
. There's no magic here. Usehelp
to figure out the commands available ortype <command>
to figure out what type<command>
is (e.g. a builtin, external command, function or alias).
– 0xC0000022L
Sep 19 '17 at 12:29
Basile, you are quite right. I hadn't spotted the significance of thecommand
command. Which is fact ensures that /usr/bin/time is called. This means that the following two statements are compatible:$ command time -f %e sleep 4
and$ /usr/bin/time -f %e sleep
– Paul Pritchard
Sep 20 '17 at 6:38
add a comment |
1
time
is also a builtin shell.
– Basile Starynkevitch
Sep 19 '17 at 11:57
If you want to ensure you're running the command, usecommand
, if you want to ensure you're running the builtin, usebuiltin
. There's no magic here. Usehelp
to figure out the commands available ortype <command>
to figure out what type<command>
is (e.g. a builtin, external command, function or alias).
– 0xC0000022L
Sep 19 '17 at 12:29
Basile, you are quite right. I hadn't spotted the significance of thecommand
command. Which is fact ensures that /usr/bin/time is called. This means that the following two statements are compatible:$ command time -f %e sleep 4
and$ /usr/bin/time -f %e sleep
– Paul Pritchard
Sep 20 '17 at 6:38
1
1
time
is also a builtin shell.– Basile Starynkevitch
Sep 19 '17 at 11:57
time
is also a builtin shell.– Basile Starynkevitch
Sep 19 '17 at 11:57
If you want to ensure you're running the command, use
command
, if you want to ensure you're running the builtin, use builtin
. There's no magic here. Use help
to figure out the commands available or type <command>
to figure out what type <command>
is (e.g. a builtin, external command, function or alias).– 0xC0000022L
Sep 19 '17 at 12:29
If you want to ensure you're running the command, use
command
, if you want to ensure you're running the builtin, use builtin
. There's no magic here. Use help
to figure out the commands available or type <command>
to figure out what type <command>
is (e.g. a builtin, external command, function or alias).– 0xC0000022L
Sep 19 '17 at 12:29
Basile, you are quite right. I hadn't spotted the significance of the
command
command. Which is fact ensures that /usr/bin/time is called. This means that the following two statements are compatible: $ command time -f %e sleep 4
and $ /usr/bin/time -f %e sleep
– Paul Pritchard
Sep 20 '17 at 6:38
Basile, you are quite right. I hadn't spotted the significance of the
command
command. Which is fact ensures that /usr/bin/time is called. This means that the following two statements are compatible: $ command time -f %e sleep 4
and $ /usr/bin/time -f %e sleep
– Paul Pritchard
Sep 20 '17 at 6:38
add a comment |
try this, it runs a simple command with arguments and puts the times $real $user $sys and preserves the exit code.
It also does not fork subshells or trample on any variables except real user sys, and does not otherwise interfere with the running of the script
timer ()
time "$@" ; 2>$_ _>&- ; _>&2 2>"/tmp/$$.$BASHPID.$#FUNCNAME[@]"
set -- $?
read -d "" _ real _ user _ sys _ < "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
rm -f "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
return $1
e.g.
timer find /bin /sbin /usr rm /tmp/
echo $real $user $sys
note: it only times the simple command not a pipeline, whose components are run in a subshell
This version allows you to specify as $1 the name of the variables that should receive the 3 times:
timer ()
time "$@:4" ; 2>$_ _>&- ; _>&2 2>"/tmp/$$.$BASHPID.$#FUNCNAME[@]"
set -- $? "$@"
read -d "" _ "$2" _ "$3" _ "$4" _ < "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
rm -f "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
return $1
e.g.
timer r u s find /bin /sbin /usr rm /tmp/
echo $r $u $s
and may be useful if it ends up being called recursively, to avoid trampling on times; but then r u s etc should be declared local in their use.
http://blog.sam.liddicott.com/2016/01/timeing-bash-commands.html
add a comment |
try this, it runs a simple command with arguments and puts the times $real $user $sys and preserves the exit code.
It also does not fork subshells or trample on any variables except real user sys, and does not otherwise interfere with the running of the script
timer ()
time "$@" ; 2>$_ _>&- ; _>&2 2>"/tmp/$$.$BASHPID.$#FUNCNAME[@]"
set -- $?
read -d "" _ real _ user _ sys _ < "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
rm -f "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
return $1
e.g.
timer find /bin /sbin /usr rm /tmp/
echo $real $user $sys
note: it only times the simple command not a pipeline, whose components are run in a subshell
This version allows you to specify as $1 the name of the variables that should receive the 3 times:
timer ()
time "$@:4" ; 2>$_ _>&- ; _>&2 2>"/tmp/$$.$BASHPID.$#FUNCNAME[@]"
set -- $? "$@"
read -d "" _ "$2" _ "$3" _ "$4" _ < "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
rm -f "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
return $1
e.g.
timer r u s find /bin /sbin /usr rm /tmp/
echo $r $u $s
and may be useful if it ends up being called recursively, to avoid trampling on times; but then r u s etc should be declared local in their use.
http://blog.sam.liddicott.com/2016/01/timeing-bash-commands.html
add a comment |
try this, it runs a simple command with arguments and puts the times $real $user $sys and preserves the exit code.
It also does not fork subshells or trample on any variables except real user sys, and does not otherwise interfere with the running of the script
timer ()
time "$@" ; 2>$_ _>&- ; _>&2 2>"/tmp/$$.$BASHPID.$#FUNCNAME[@]"
set -- $?
read -d "" _ real _ user _ sys _ < "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
rm -f "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
return $1
e.g.
timer find /bin /sbin /usr rm /tmp/
echo $real $user $sys
note: it only times the simple command not a pipeline, whose components are run in a subshell
This version allows you to specify as $1 the name of the variables that should receive the 3 times:
timer ()
time "$@:4" ; 2>$_ _>&- ; _>&2 2>"/tmp/$$.$BASHPID.$#FUNCNAME[@]"
set -- $? "$@"
read -d "" _ "$2" _ "$3" _ "$4" _ < "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
rm -f "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
return $1
e.g.
timer r u s find /bin /sbin /usr rm /tmp/
echo $r $u $s
and may be useful if it ends up being called recursively, to avoid trampling on times; but then r u s etc should be declared local in their use.
http://blog.sam.liddicott.com/2016/01/timeing-bash-commands.html
try this, it runs a simple command with arguments and puts the times $real $user $sys and preserves the exit code.
It also does not fork subshells or trample on any variables except real user sys, and does not otherwise interfere with the running of the script
timer ()
time "$@" ; 2>$_ _>&- ; _>&2 2>"/tmp/$$.$BASHPID.$#FUNCNAME[@]"
set -- $?
read -d "" _ real _ user _ sys _ < "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
rm -f "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
return $1
e.g.
timer find /bin /sbin /usr rm /tmp/
echo $real $user $sys
note: it only times the simple command not a pipeline, whose components are run in a subshell
This version allows you to specify as $1 the name of the variables that should receive the 3 times:
timer ()
time "$@:4" ; 2>$_ _>&- ; _>&2 2>"/tmp/$$.$BASHPID.$#FUNCNAME[@]"
set -- $? "$@"
read -d "" _ "$2" _ "$3" _ "$4" _ < "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
rm -f "/tmp/$$.$BASHPID.$#FUNCNAME[@]"
return $1
e.g.
timer r u s find /bin /sbin /usr rm /tmp/
echo $r $u $s
and may be useful if it ends up being called recursively, to avoid trampling on times; but then r u s etc should be declared local in their use.
http://blog.sam.liddicott.com/2016/01/timeing-bash-commands.html
edited Jun 7 '16 at 9:17
answered Jan 27 '16 at 10:12
Sam LiddicottSam Liddicott
1093
1093
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f12068%2fhow-to-measure-time-of-program-execution-and-store-that-inside-a-variable%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
-bash, shell-script, time
The most direct way to get the data and handle it while still letting it run normally would be to do it in a C program using
fork()
,execvp()
andwait3()/wait4()
. This is ultimately what time and friends are doing. I'm not aware of a simle way to do it in bash/perl without redirecting to a file or similar approach.– penguin359
Apr 26 '11 at 22:20
There is a related question that you might find interesting going on here.
– Caleb
Apr 26 '11 at 23:09
@Caleb: thanks. Indeed interesting. However, for my purposes it's sufficient to do it in a script.
– 0xC0000022L
Apr 26 '11 at 23:28