Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

  (email not shown publicly)
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Wednesday February 13, 2008
10:49 AM

Where's My Catalyst Server?

[ #35647 ]

It's a nasty hack, but I got sick and tired of always doing the following:

  1. Start our Catalyst server
  2. Launch a second program which needs the server
  3. Cuss because I've gotten the host/port wrong again.

So I wrote something like this:

use List::MoreUtils 'uniq';
use Net::Domain 'hostname';
use Getopt::Long;

sub get_cat_host_port {
    my ( $app_name, $user ) = @_;
    $app_name .= "";
    $user ||= [getpwuid($<)]->[0];

    # The sed bit is embarrassing but needed on a Cat restart
    # when the shell quotes things :/
    chomp(my @processes
      = uniq `ps -ef|grep "$user.*$app_name"|grep -v grep|sed -e 's/"//g' -e 's/.* script//'`
    if ( @processes > 1 ) {
        require Data::Dumper;
        $Data::Dumper::Indent = 1;
        warn Data::Dumper->Dump( [\@processes], ['*processes'] );
        die "Found more than one $app_name server for ($user)";
    unless (@processes) {
        die "Could not find any $app_name servers for ($user)";
    local @ARGV = split /\s+/ => $processes[0];
    local $SIG{__WARN__} = sub {
        my $warning = shift;
        return if $warning =~ /Unknown option/; # wish this was configurable
        'port=i' => \my $port,
        'host=s' => \my $host,
    $port ||= 3000;
    $host ||= hostname();
    return ( $host, $port );

It's now tucked away in a tools library so we can reuse this.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • You had

    ps -ef|grep "$user.*$app_name"|grep -v grep|sed -e 's/"//g' -e 's/.* script//'

    If you're using all GNU tools, you can improve that shell command a bit:

    ps --no-header --user "$user" --format command | grep "^$app_name" | sed 's/"//g;s/.* script//'

    • No grep for user (which may be output numerically under some conditions)
    • --no-header and --format mean you get only what you want out of ps
    • No grep -v to remove grep
    • No -e on the sed commands
    • Combined the sed commands into a single sed exp
    • We're on Solaris. Many tools and options I took for granted on *nix systems simply aren't available. For example, the ps command does recognize the --no-header or --user options.

      Other annoyances: tar doesn't recognize the z modifier and the absolute worst: grep doesn't recognize -r. No recursive grep. The options are either doing a find and piping the results to grep or using ack [] (the latter of which is lovely, I might add).

      • Many Solaris admins replace the default tar with GNU tar, perhaps installing it as gtar, giving users their choice.

        Some admins get their panties in a bunch over the fact that GNU tar is not POSIX compliant, but most people shrug and decided they'd rather have something useful over some notion of correct, especially when Sun's tar can't handle paths over 256 characters.

        That may be specifically relevent to you as a Catalyst user given this thread [] from comp.unix.solaris.

      • can't you simply install some packages? is a good place.

        Anyway my point was: don't forget /proc and magic ps ;) perl -lpe 's{\0}{ }g' /proc/*/cmdline

        cheers --stephan p.d at least if you have a decent support for it always worth to remember.
  •     # The sed bit is embarrassing but needed on a Cat restart
        # when the shell quotes things :/
        chomp(my @processes
          = uniq `ps -ef|grep "$user.*$app_name"|grep -v grep|sed -e 's/"//g' -e 's/.* script//'`

    Why use Sed at all? Won't it work to do the transformations on Perl list elements rather than on lines in the shell?

      chomp my @processes = uniq map { tr/"//d; s/.* script//; $_ }
        `ps -ef|grep "$user.*$app_nam

    • Why use the shell at all? Shame on you both with your platform specific solutions.

      See Proc::ProcessTable []

      • I wholeheartedly use and recommend Proc::ProcessTable. That is until I had to use it [] on an Opteron Solaris 10 box. I was in a hurry so I just said bugger it and scraped the output of ps instead.
        • There's a bug in Proc::ProcessTable, though I couldn't tell you what it is offhand. The sys-proctable [] library, which started as a port of Dan's work, picks up other processes just fine.

          The only security change for /proc they made between 9 and 10 that I'm aware of is the cmdline information is now restricted to 80 characters unless you own the process. Which, in practice, meant we had to shell out to use /usr/ucb/ps -auxwww so we could distinguish between the Java processes with ridiculously long command

  • This is screaming out for something to be bundled with Cat, or for a Firefox plugin, or something...