#!/usr/local/bin/perl5.6.1 -w

use strict;
use IO::File;
use Getopt::Std;

# If the user does have a home .lsbatch directory, we can use LSF's
# bpeek

my $home = (getpwuid($>))[7];

if ( -d "$home/.lsbatch" ) {
    exec('bpeek', @ARGV);
    die "Could not exec bpeek : $!\n";
}

my %opt;

my @bjob_opts = ('-l', '-r');

getopts("fq:m:J:", \%opt);

# Quote options before passing them on

foreach ('q', 'm', 'J') {
    if (exists($opt{$_})) {
        push @bjob_opts, $_;
        push @bjob_opts, $opt{$_} =~ /\s/ ? "\"$opt{$_}\"" : $opt{$_};
    }   
}

# The record separator in bjobs output

local $/ = "\n" . '-' x 78 . "\n";

local $, = ' ';

my $fh = IO::File->new("bjobs @bjob_opts @ARGV|")
    or die "Could not run bjobs : $!\n";

my ($jobid, $exec_home, $exec_host, $status, $dh);

while (<$fh>) {
    # bjobs output is annoyingly wrapped with loads of excess
    # whitespace.  Remove it.
    s/\n[ \t]+//sg;

    if (($jobid, $status, $exec_host, $exec_home) =
	/Job <(\d+)>.*Status <(\w+)>.*Started on <(\w+)>.*Execution Home <([^>]+)>/s) {
	if ($status eq 'RUN') {

            # Get the list of files associated with this job's execution
	    local $/ = "\n";
	    my @files = `lsrun -m $exec_host ls $exec_home/.lsbatch`;

            # Find the stdout file, and display it
	    my ($outfile) = grep { /$jobid\.out$/ } @files;
            if (defined($outfile)) {
                if (exists($opt{'f'})) {
                    exec("lsrun -S -m $exec_host tail -f $exec_home/.lsbatch/$outfile");
                    die "Could not exec lsrun : $!\n";
                }
	        print "\n<< stdout >>\n";
	        system("lsrun -m $exec_host cat $exec_home/.lsbatch/$outfile");
            }

            # Find the stderr file and display it
	    my ($errfile) = grep { /$jobid\.err$/ } @files;
            if (defined($errfile)) {
	        print "\n<< stderr >>\n";
	        system("lsrun -m $exec_host cat $exec_home/.lsbatch/$errfile");
            }
	} else {
	    print "Job <$jobid> not currently running\n";
	}
    } else {
	print "Could not find execution home directory - job is probably not producing output.\n";
    }
}

$fh->close;

__END__

=head1 NAME

bpeek.pl - Wrapper script for bpeek

=head1 SYNOPSIS

bpeek.pl [-f] [-q queue_name | -m host_name | -J job_name | jobId | "jobId[index]" ]

=head1 DESCRIPTION

Wrapper for the LSF bpeek(1) command.  Allows the standard out and standard
error output of a batch job to be viewed while the job is running.  The -f
option allows the output to be followed (c.f. tail -f).

Unlike bpeek(1), bpeek.pl will work even when the lsbatch files are not
kept in the users' home directory.

=head1 SEE ALSO

bpeek(1)

=head1 AUTHOR

Tim Cutts

=head1 HISTORY

 # $Log: bpeek.pl,v $
 # Revision 1.2  2003/03/03  17:12:52  rmd
 # Now uses perl5.6.1
 #
 # Revision 1.1  2003/02/06  17:38:31  rmd
 # Initial revision
 #

