loading...
Cover image for Monitor the performance of any command line program with this single command

Monitor the performance of any command line program with this single command

agrim profile image Agrim Prasad Updated on ・3 min read

This post was originally published on my blog, find original post here.

I have been executing a lot of bash scripts and one-off processes on the linux command line recently, and was curious about how to monitor the CPU and memory usage of these processes as quickly as possible. Some of these processes seemed to bring my linux box to a screeching halt, and without instant resource monitoring I couldn't tell whether such a process was eating excessive RAM or CPU (or both?!)

What people usually do

Conventionally, suggestions about process monitoring involve the following:

  1. Run your command line process.

  2. Get the PID of the process with ps aux command which is generally available for both Linux and Mac.

  3. Run the utility top with

    top -p <pid>
    

    on Linux or

    top -pid <pid>
    

    on Mac OS.

However, I wanted to run commands which would exit within a few seconds, before I could run top to start monitoring them. How could I start monitoring these commands as soon as they were invoked?

What can we do better

As always, Unix has an answer:

  1. Run your command in the background and pipe the output to /dev/null so that it doesn't get printed on the command line while you are monitoring the CPU/memory usage, e.g.

    unzip ~/Downloads/sample.zip > /dev/null &
    
  2. Echo the PID of this background process with

    echo $!
    
  3. Combine the two, and pass the pid of the process to top with

    top -p `{ unzip ~/Downloads/sample.zip > /dev/null & } && echo $!`
    

    on linux or

    top -pid `{ unzip ~/Downloads/sample.zip > /dev/null & } && echo $!`
    

    on Mac OS.

BOOM, you just started monitoring your process immediately with a single command. Now isn't that peachy!

Bonus: Use htop instead of top

I ❤️ htop which is a process monitoring utility available for both linux and Mac OS. Come on, you've got colours! Let's use this instead of top for better insight into the CPU/memory performance of our processes.

  1. Install htop with

    sudo apt-get install htop
    

    on Ubuntu or

    brew install htop
    

    on Mac OS with Homebrew

  2. Run our previous monitoring command using htop instead of top for monitoring with

    htop -p `{ unzip ~/Downloads/sample.zip > /dev/null & } && echo $!`
    

See the single command in action below!
Single command process monitoring with htop

Double Bonus: Style your editor for a more beautiful htop

Saw some chatter on Twitter about this post which mentioned that I should have added information about the terminal theme I'm using here, since htop gets styled by the terminal and theme in use. I totally agree, so here's my setup:

  1. Terminal emulator: iTerm2 Awesome Mac OS Terminal replacement with cool features such as grid tabs and more.
  2. Unix shell + theming framework: zsh + oh-my-zsh Check out this awesome post about how to install these (similar steps on Ubuntu or Mac OS)
  3. oh-my-zsh theme: Default theme robbyrussell. After setting up oh-my-zsh, you can specify the desired theme in the ~/.zshrc file, e.g. ZSH_THEME="robbyrussell"

Posted on by:

agrim profile

Agrim Prasad

@agrim

Looking for any discussions where you have strong opinions,because I probably do. Mostly work in Golang nowadays, although have worked with Python and Javascript in the past.

Discussion

markdown guide
 

Current style recommendations for shell scripts discourages the use of back-ticks. One would more typically do something like:

top -p $( gunzip -c LARGE_ARCHIVE_FILE.tgz > /dev/null & echo $! )

Using the $() method allows for nesting of commands without jumping through hoops to escape one command-execution nested within another)

 

Thanks for the tip Thomas. I usually do use $() but didn't know that you don't need to escape nested command execution with it. Initially I used $() along with {} and it lead to errors on Mac (but not on Linux), so I switched to back-ticks which worked on both.

I'll update the article once I get near my computer and can test this out on both Mac and Linux, thanks again.

 

Yeah... Being a long-time abuser of nested subshells, used to frustrate the hell out of me once I had to go more than about two subshells deep ...Sooner if one or more of those subshells required single- and/or double-quotes for some of their functionality.

Wasn't really until I started adding shellcheck to my TravisCi recipes that I habituated to the $() method. That tool also caused me to start moving off a few other habitual things that had been placed on the deprecation (but had worked for decades so were just "finger memory").

 

I'd definitely suggest checking out glances: It's an alternative to top/htop entirely written in Python, and it's a lot easier on the eyes/to parse IMO.