Quick way to check elapsed time for a command in your terminal
Want to know how long a shell command takes? The time utility is a quick and easy solution. But that's not all - there are other tools at your disposal, like $SECONDS and shell-specific features in NuShell and PowerShell
If you are reading this, chances are you need to figure out what is going on in a piece of software inside a command line interface. If you are running any type of OS that is "Linux"-like, great news! You most likely already have all the tools you need. I shall start with those and move on to the less common use-cases such as NuShell and PowerShell.
Time Command
This is the one I'd recommend testing first. It is an utility that times a command that you pass along as an argument, then returns its results and the duration of the runtime. Here is the description from its manual:
The time utility executes and times the specified utility. After the utility finishes, time writes to the standard error stream, (in seconds): the total time elapsed, the time used to execute the utility process and
the time consumed by system overhead.
It is as simple as it sounds, you use time
before the command you would usually type in your terminal and just like magic:
nu โ : time sleep 10
10.00 real 0.00 user 0.00 sys
Just as described in the tin: printed in the stderr there's the time used for the task at hand. Yes, I ran a 10 second sleep and waited for the output to add in here like a maniac.
Just a few notes you might need to know before using time
everywhere:
- The
time
utility is not included in all distributions, you might not be able to find it readily in all container images or runtimes. - This relies on your $PATH environment variable to find the executables you might need. Sounds simple, but caught me once or twice. Just sharing to make sure you do not have to scramble like I did.
- Use the
-h
flag for human readable format; I know, it's not thehelp
flag like most tools use-h
for. This is helpful for whenever you have too long of an execution time and you just want something readable; it breaks down the minutes and hours from the seconds elapsed. This is not something you would usually want in an automation though. - You can use this as your tool for keeping track of execution with the
-a
and-o
flags.-o
sets the output file for the time utility, and-a
is used to append instead of overwriting the file. This way you can set a continuous file with all the elapsed times of some sort of cronjob you have - this has helped me find a few bugs in cronjobs that were not executing properly.
$SECONDS
You probably did not know that, but your computer is counting for you. No, seriously, try it for yourself! Type echo $SECONDS
in your terminal right now and take a look:
fancygui% echo $SECONDS
10
GASP! It just counted the 10 seconds it took for me to write that single command! (Or maybe I just wanted it to be the same number 10 in the sleep example, your choice. I will not judge)
In all seriousness now, you can probably now see the power of this. This environment variable is updated with the elapsed seconds of your shell process. So, if you have something running you can check how long it takes by either taking the difference of your $SECONDS variable before and after your command or you can do the thing that everyone does and it is better: set $SECONDS to zero before running your commands:
fancygui% SECONDS=0;sleep 10;echo "Elapsed: $SECONDS"
Elapsed: 10
I shall not stop using 10 for sleeps if you don't stop me. Anyways...
As you can see, this can be much simpler in a few places that you want to have a quick check and time
is not readily available to install. I find it very useful for some pipeline work I do.
NuShell
"I use NuShell, btw". Is it the new "Arch" of Shells? Regardless, it is awesome and I use it as my default shell, but it does not count my $SECONDS as zsh
and bash
might do - sad times - but it has something I believe it is better:
๐
nu โ : let now = date now; sleep 10sec; $now - (date now)
-10sec 1ms 974ยตs
Look at the way it displayed the difference of the two "dates". Everything in NuShell has a type and it is much easier to get data like this by just operating on it.
Anyways, 'fanboying' aside, this is how you can check the elapsed time between commands. You will see the odd ms or microsecond here and there that it takes for the process to be scheduled and terminated, but that's what you get when you are looking that close to the execution time. And you can always convert the data to something you prefer. A difference of datetime objects in nushell produces a duration object:
nu โ : $now - (date now) | describe
duration
If there is any interest to go more into detail for NuShell or any other entries, feel free to let me know. But for now let's look into PowerShell's version.
PowerShell
Oh PowerShell, the weird one. The Shell that I don't even know if I should call it that. It feels like you are "massaging" .NET objects and not at the same time. NuShell feels oddly familiar to it, and I really recommend people to take a second look at PowerShell. Especially the newer versions that are cross-platform, it is fun to write and quite versatile. But I digress.
Well, it is not too different from the NuShell solution, and I still believe it's awesome:
PS /Users/fancygui> $now = Get-Date; sleep 10; $now - (Get-Date)
Days : 0
Hours : 0
Minutes : 0
Seconds : -10
Milliseconds : -32
Ticks : -100327890
TotalDays : -0.000116120243055556
TotalHours : -0.00278688583333333
TotalMinutes : -0.16721315
TotalSeconds : -10.032789
TotalMilliseconds : -10032.789
Yep, be baffled, 10 seconds again. Ok, jokes aside, feels very similar to NuShell, does it not? Feels more than just an output to stderr:
PS /Users/fancygui> ($now - (Get-Date)).GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True TimeSpan System.ValueType
It is just as simple to get an object of type TimeSpan. Another Object, another shell that tries to be similar to a programming language. Well, you probably already know that PowerShell is powered - pun intended - by .NET. Really powerful stuff!
You can then use this TimeSpan object in any way you intend. This should simplify your life when trying to get a simple execution time from a command.
If you still want to know more or need some help navigating your environments and understanding what you can do to better solve your issues at hand, feel free to reach out to FancyWhale, we are here to help! Also, do not forget to subscribe to our blog here and get updates on the things we are up to.