Senseless Acts of Perl

At work I spend alot of time working on one of our Solaris dev servers via xterm. Via many xterms simultaneously, most of the time. Since I run a local X client on my PC under cygwin, I have a shell script that I run locally that connects to the dev box and launches three xterms in pre-determined screen locations, setting DISPLAY along the way.

Over the course of a busy morning, this number can grow. Since I’m still on a Windows PC, however, I do tend to use my task bar to find windows. Having six or more taskbar buttons that all say “xterm” isn’t very helpful. For a while I tried setting my titles to reflect what I’m doing in each xterm, but this futile. Partially because I often create, destroy, or repurpose xterms on a whim; but largely because I’m lazy.

A while ago, I updated my launch script to label my initial three windows Alpha, Beta, and Gamma. While the names aren’t very descriptive, it does differentiate the windows, and I can usually remember what each window is being used for. When I start launching additional xterms, things can get confusing; I try to remember to add a -title and pick a Greek letter not in use, but I did mention I’m lazy, right? So today, I decided to do something about it.

The result is addterm, one of the more senseless perl scripts I’ve ever bothered with. When run, it creates a new xterm with the title set to the name of the first greek letter not currently in use. If all 24 greek letters are in use, and error message is printed and no xterm is launched. This is a feature, not a bug. Close some windows! The version below is my OS X port. :

#!/usr/bin/perl -w

my $user = `whoami`;
my @ps = split("\n", `ps -o command -U $user`);
my @alpha = qw/Alpha Beta Gamma Delta Epsilon
               Zeta Eta Theta Iota Kappa Lambda
               Mu Nu Xi Omicron Pi Rho Sigma
               Tau Upsilon Phi Chi Psi Omega/;
my $k=0;
my %greek = map {$_=>$k++} @alpha;

for(@ps) {
    my ($title) = /^xterm\s+-title\s+([^\s]+)/ or next;
    $alpha[$greek{$title}]=) {
        $next = $_;
        last;
    }
}

if (defined $next) {
    open STDERR, '>/dev/null'; #discard xterm's whining
    system("xterm -title $next & ");
} else {
    print STDERR "ERROR: No greek letters free!\n";
}

This required a port from the original Solaris version because the script uses ps to look for running xterms. The Solaris version uses ps -o args -u $user. The command should list (only) the full command + args for every process for the username $user. If you want to use this on another *nix, just test your ps command first and adjust accordingly. You could also change the Greek letters to another finite set, just remember to update the error message.

Of dubious interest is that fact that I used an array to keep the letters in order and a hash to allow quick indexing into the array. I dislike having to store the letters twice, but this seemed the best solution. I have a vague sense that some kind of tied vars may do this more elegantly, but my perl-fu isn’t quite that strong without cracking the Camel; did I mention I’m lazy? Perhaps tommorow. Improvements welcomed.

Both comments and pings are currently closed.

7 Responses to “Senseless Acts of Perl”

  1. Craig Morgan Says:

    Multiple xterms … use screen!<br/>

    Unless you actually require the ability to monitor or compare the output across the different windows, ie. from side to side windows, then it might be worth investing a few minutes in investigating the utility ‘screen’.

    Although it might seem like a step backwards (ie. GUI to CLI), it’s actually a great productivity enhancer if used carefully. You get multiple simultaneous sessions, in one ‘window’, with the ability to detach and re-attach to running ttys, monitor ttys for activity, etc.

    Once you’ve used it there is no going back …

    Just a happy ‘screen’ user ;-)

    More info at http://www.gnu.org/software/screen/screen.html

    Craig

  2. Jason Says:

    Screen?<br/>

    Thanks Craig! I’ve actually been jonesing for tabbed term app like iTerm on my Mac; but I’m a bit limited in what I can run here at work. I actually read something on another blog recently mentioning screen (the.TaoOfMac.com, I think) which got me interested. I’ll definately check it out. Thanks!

  3. Jason Says:

    No Gnus is Bad News<br/>

    Now I remember why I haven’t checked it out yet… I tried to take a look last night and gnu.org seemed to be down (no response). I’m getting the samething now from another location. I’ll keep trying.

  4. Craig Morgan Says:

    Revisit: Multiple xterms … use screen!<br/>

    Try this kuro5hin article (http://www.kuro5hin.org/story/2004/3/9/16838/14935) turned up by google for a reasonable intro … BTW, screen is already installed in OSX as part of Apples distribution anyway, and its a relatively recent version.

    I would certainly suggest that you configure a .screerc the first time that you use the sw, as I find it helps new users envisage WTH is going on!

    There is a suitable one quoted in the comments of the above article to get you started. Another useful site is http://www.guckes.net/screen/

    HTH

    Craig

  5. Jason Clark Says:

    Screen in use<br/>

    Thanks Craig. I got the source compiled under solaris at work. I think I’m getting the hang of it. I found guckes.net; but I hadn’t seen the kiro5hin article yet. I’ll have to give it a read.

    I’m not sure I’m completely comfortable with it yet, but I’m working on it. I modified my default connect script to launch each of my three default xterms with screen. These xterms are automatically located to not overlap, so I can see three things at once. The multiplied by screen should be enough terms, I hope. As for OS X; I’m already using iTerm (http://jclark.org/weblog/CoolStuff/iTerm.html), and I really prefer visible tabs on screen.

  6. Mark Stosberg Says:

    screenrc example<br/>

    Jason,

    Here’s some examples from .screenrc to make life easier. It means when I start screen, a few screens always start with predefined names, with numbers starting at 1 rather than the default of zero. I just do simple ‘su’ commands here, but you could just as easily have a screen that immediately ssh’s to another machine:

    Make my screens start at 1 rather than 0

    bind c screen 1

    set up 4 screens for myself

    screen -t mark 1 screen -t sumsault 2 su -m sumsault screen -t root 3 su -m screen -t legalsk8 4 su -m legalsk8

  7. Jason Says:

    my lousy comment system<br/>

    Mark-

    Thanks for the example. I really do find screen a big help; and I’ve been meaning to look into a .screenrc file. Unfortunately, my lousy comments system mutilated your post. I’m getting ready to overhaul my comments system using Markdown to format comments; once I do that your comment should automagically return to legibility. Meanwhile, a quick view-source will show the curious your example complete with linebreaks.