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;








55















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.



  1. 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.

  2. 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.










share|improve this question
























  • 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











  • @Caleb: thanks. Indeed interesting. However, for my purposes it's sufficient to do it in a script.

    – 0xC0000022L
    Apr 26 '11 at 23:28

















55















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.



  1. 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.

  2. 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.










share|improve this question
























  • 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











  • @Caleb: thanks. Indeed interesting. However, for my purposes it's sufficient to do it in a script.

    – 0xC0000022L
    Apr 26 '11 at 23:28













55












55








55


19






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.



  1. 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.

  2. 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.










share|improve this question
















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.



  1. 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.

  2. 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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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











  • @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











  • 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










9 Answers
9






active

oldest

votes


















78














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





share|improve this answer




















  • 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






  • 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











  • @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 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



















16














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).






share|improve this answer























  • Wow, a lot to test. Thanks a lot for the extensive reply. +1.

    – 0xC0000022L
    Apr 26 '11 at 23:25


















7














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.






share|improve this answer


















  • 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







  • 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



















4














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.






share|improve this answer






























    4














    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"





    share|improve this answer






























      4














      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.





      share|improve this answer























      • 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


















      1














      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"





      share|improve this answer























      • /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


















      1














      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.






      share|improve this answer


















      • 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, 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



















      0














      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






      share|improve this answer

























        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
        );



        );













        draft saved

        draft discarded


















        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









        78














        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





        share|improve this answer




















        • 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






        • 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











        • @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 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
















        78














        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





        share|improve this answer




















        • 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






        • 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











        • @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 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














        78












        78








        78







        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





        share|improve this answer















        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






        share|improve this answer














        share|improve this answer



        share|improve this answer








        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 as DIFF=$((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 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






        • 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 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













        • 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






        • 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











        • @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 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








        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














        16














        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).






        share|improve this answer























        • Wow, a lot to test. Thanks a lot for the extensive reply. +1.

          – 0xC0000022L
          Apr 26 '11 at 23:25















        16














        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).






        share|improve this answer























        • Wow, a lot to test. Thanks a lot for the extensive reply. +1.

          – 0xC0000022L
          Apr 26 '11 at 23:25













        16












        16








        16







        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).






        share|improve this answer













        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).







        share|improve this answer












        share|improve this answer



        share|improve this answer










        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

















        • 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











        7














        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.






        share|improve this answer


















        • 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







        • 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
















        7














        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.






        share|improve this answer


















        • 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







        • 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














        7












        7








        7







        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.






        share|improve this answer













        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.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Apr 26 '11 at 19:43









        marinusmarinus

        1,6761110




        1,6761110







        • 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







        • 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













        • 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







        • 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








        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












        4














        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.






        share|improve this answer



























          4














          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.






          share|improve this answer

























            4












            4








            4







            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.






            share|improve this answer













            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.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jan 17 '16 at 14:57









            kenorbkenorb

            9,111374112




            9,111374112





















                4














                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"





                share|improve this answer



























                  4














                  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"





                  share|improve this answer

























                    4












                    4








                    4







                    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"





                    share|improve this answer













                    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"






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Aug 1 '16 at 13:46









                    loretoparisiloretoparisi

                    190213




                    190213





















                        4














                        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.





                        share|improve this answer























                        • 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















                        4














                        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.





                        share|improve this answer























                        • 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













                        4












                        4








                        4







                        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.





                        share|improve this answer













                        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.






                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        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

















                        • 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











                        1














                        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"





                        share|improve this answer























                        • /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















                        1














                        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"





                        share|improve this answer























                        • /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













                        1












                        1








                        1







                        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"





                        share|improve this answer













                        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"






                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        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 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

















                        • /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
















                        /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











                        1














                        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.






                        share|improve this answer


















                        • 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, 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
















                        1














                        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.






                        share|improve this answer


















                        • 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, 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














                        1












                        1








                        1







                        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.






                        share|improve this answer













                        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.







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        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, 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













                        • 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, 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








                        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












                        0














                        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






                        share|improve this answer





























                          0














                          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






                          share|improve this answer



























                            0












                            0








                            0







                            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






                            share|improve this answer















                            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







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Jun 7 '16 at 9:17

























                            answered Jan 27 '16 at 10:12









                            Sam LiddicottSam Liddicott

                            1093




                            1093



























                                draft saved

                                draft discarded
















































                                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.




                                draft saved


                                draft discarded














                                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





















































                                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

                                Popular posts from this blog

                                Frič See also Navigation menuinternal link

                                Identify plant with long narrow paired leaves and reddish stems Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?What is this plant with long sharp leaves? Is it a weed?What is this 3ft high, stalky plant, with mid sized narrow leaves?What is this young shrub with opposite ovate, crenate leaves and reddish stems?What is this plant with large broad serrated leaves?Identify this upright branching weed with long leaves and reddish stemsPlease help me identify this bulbous plant with long, broad leaves and white flowersWhat is this small annual with narrow gray/green leaves and rust colored daisy-type flowers?What is this chilli plant?Does anyone know what type of chilli plant this is?Help identify this plant

                                fontconfig warning: “/etc/fonts/fonts.conf”, line 100: unknown “element blank” The 2019 Stack Overflow Developer Survey Results Are In“tar: unrecognized option --warning” during 'apt-get install'How to fix Fontconfig errorHow do I figure out which font file is chosen for a system generic font alias?Why are some apt-get-installed fonts being ignored by fc-list, xfontsel, etc?Reload settings in /etc/fonts/conf.dTaking 30 seconds longer to boot after upgrade from jessie to stretchHow to match multiple font names with a single <match> element?Adding a custom font to fontconfigRemoving fonts from fontconfig <match> resultsBroken fonts after upgrading Firefox ESR to latest Firefox