Vimpress to edit/publish WordPress posts … At least it is not the <ESC> key!
Apr 15

There’s been a lot of people on the blogosphere reporting shell history. The idea is to know what kind of commands different people use on their shell - kinda geeky, but none the less. Here’s the command most are using:

  history|awk '{a[$2]++ } END{for(i in a){print a[i] " " i}}'|sort -rn|head

A Perl enthusiast that I am, I started out to do the same in Perl instead of awk. I started writing a script hotlist that will get the shell history, count unique commands and sort them in descending order of the count. Seems very straightforward. Turns out, its only straightforward - without the very.

Since history is a built-in shell command, it cannot called it with the qx// or back-tick (``) syntax of Perl to fetch shell history. I resorted to Google to find a solution, but could not find one easily. After some help from clpm, I came up with this:

#!/usr/bin/perl

use strict;
use warnings;

my %hist = ();
my @hist;

$hist{(split /\s+/)[3]}++
  foreach ((-p STDIN) ? <STDIN> : `$ENV{'SHELL'} -c history`);

print map {"$hist{$_} : $_\n"}
        sort {$hist{$b} <=> $hist{$a}}
          keys %hist;

To use shell’s built-in commands, you must invoke the shell and have it execute the built-in command. In the above script, that is done with `$ENV{'SHELL'} -c history`, which in my case expands to `/usr/local/bin/tcsh -c history` since I use t-shell. The shell can be invoked by qx// or back-tick (``) to collect the output.

You can use this script in two flavors:

  % hotlist
  % history | hotlist

The first flavor starts a new shell and calls the history command in it. So you get the information from saved shell history. It does not contain commands form the active shell. If you want to include the active shell too, use the second flavor. Where you pipe the current shell’s history into the script.

Hopefully, this will help the next person who wants to use shell built-in commands in Perl. Like I said, I am a Perl enthusiast, not an expert, so this may not be the best solution.

I am sure some Perl guru will manage to cram all that in a one-liner, but that was not my intent.

Leave a Reply