0

How to subtract time and show seconds or miliseconds?

  1. begin_time=$(date)
  2. run something to be (fast , simple and informal) check performance
  3. echo $(date) - $begin_time

of course, it is not working, how to do it?

4 Answers4

4

Bash has a built in function for this called time. Just prepend it to any command and it will time how long the command takes to run. For more info, see help time :)

[user@sol ~]$ time sleep 2

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

zsh has a similar builtin also called time, though no help page for help time. Here is sample output:

[sol ~]$ time sleep 2
sleep 2  0.00s user 0.00s system 0% cpu 2.003 total
wjandrea
  • 14,236
  • 4
  • 48
  • 98
j-money
  • 2,382
4

In addition to the time builtin, there exists /usr/bin/time, which is often more useful.

walt@bat:~(0)$ /usr/bin/time sleep 2
0.00user 0.00system 0:02.04elapsed 0%CPU (0avgtext+0avgdata 1756maxresident)k
80inputs+0outputs (1major+73minor)pagefaults 0swaps
walt@bat:~(0)$ /usr/bin/time -v sleep 2
    Command being timed: "sleep 2"
    User time (seconds): 0.00
    System time (seconds): 0.00
    Percent of CPU this job got: 0%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.00
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 1828
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 73
    Voluntary context switches: 2
    Involuntary context switches: 0
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0
walt@bat:~(0)$ 

Or, if you really want to do it by hand, read man date and use date +%s.%N (%s = seconds since Epoch, %N = nanoseconds)

waltinator
  • 36,399
4

If you are using the bash or zsh shell, and only need a resolution of seconds, then you can use their SECONDS shell variable. From man bash:

SECONDS
       Each  time  this  parameter is referenced, the number of seconds
       since shell invocation is returned.  If a value is  assigned  to
       SECONDS,  the  value  returned upon subsequent references is the
       number of seconds since the assignment plus the value  assigned.

So, if you assign a value of zero before executing your command (or sequence of commands), the subtraction is done for you.

Ex.

$ SECONDS=0 && sleep 2 && echo $SECONDS
2

Interestingly, ksh93 has a SECONDS timer, but it appears to provide millisecond resolution:

$ ksh
$ SECONDS=0 && sleep 2 && echo $SECONDS
2.002

(The Korn shell - which predates bash and zsh - is more generally able to handle non-integer shell arithmetic.)

steeldriver
  • 136,215
  • 21
  • 243
  • 336
1

Fixing up your code

(assuming you're using Bash)

begin_time=$(date +%s)  # Get seconds since Unix epoch.
sleep 2  # For example
echo $(($(date +%s) - begin_time)) seconds

This should output 2 seconds.

(N.B. Normally you should quote all expansions, but these values are guaranteed to be integers.)

Problems with your code

begin_time= date
  • For assigning the output of a command to a variable, the syntax is variable=$(command). The way you wrote it, it will call date with begin_time as an environment variable - not at all what you want.
  • date's output is locale-specific. That's why I use Unix time instead.
echo date - $(begin_time)
  • This isn't in an arithmetic context, so the minus sign is treated as a string instead of an operator. Use $((expression)).
  • To get the output of a command (command substitution), use $(command)
  • To get the value of a variable (parameter substitution), use $variable or ${variable}.
wjandrea
  • 14,236
  • 4
  • 48
  • 98