#!/usr/bin/perl -w use strict; use vars qw($VERSION); use Pod::Usage; use PBS::Client; $VERSION = $PBS::Client::VERSION; #----------------------------- # Usage: # run [command [arguments]] # run [-h | -m | -v | -l | -e] # # Example: # - Submit a.out to PBS # run a.out #----------------------------- #------------------------ # -h option; print help # -m option: print manual #------------------------ pod2usage() if (@ARGV == 1 && $ARGV[0] eq '-h'); pod2usage(-verbose => 2) if (@ARGV == 1 && $ARGV[0] eq '-m'); #-------------------------------- # -v option: print version number #-------------------------------- if (@ARGV == 1 && $ARGV[0] eq '-v') { print "$VERSION\n"; exit(0); } #----------------------- # -l option: list config #----------------------- if (@ARGV == 1 && $ARGV[0] eq '-l') { my $cfgFile = "$ENV{HOME}/.runrc"; die "No config file is found.\n" if (!-e $cfgFile); die "Config file is empty.\n" if (-z $cfgFile); system("cat $cfgFile"); exit(0); } #----------------------- # -e option: edit config #----------------------- if (@ARGV == 1 && $ARGV[0] eq '-e') { editCfg("$ENV{HOME}/.runrc"); exit(0); } #-------------------- # Get jobs from stdin #-------------------- my $JOB = join(" ", @ARGV); while (!$JOB) { print "What to do?\n"; $JOB = ; chomp $JOB; } #---------------------------- # Read config and submit jobs #---------------------------- my ($server, $cfg) = readCfg("$ENV{HOME}/.runrc"); my $pbs = PBS::Client->new; $pbs->server($server) if ($server ne ''); my $job = PBS::Client::Job->new( cmd => $JOB, %$cfg, ); my $command = (split(/\s+/, $JOB))[0]; $command =~ s/.+\///; $job->script("$command.sh") if (!defined $$cfg{script}); $job->name("$command.sh") if (!defined $$cfg{name}); $pbs->qsub($job); ########################## SUBROUTINES ########################## #------------------- # Config file editor #------------------- sub editCfg { my ($cfgFile) = @_; my $editor = $ENV{EDITOR}; $editor = $ENV{VISUAL} if (!$editor); $editor = `which $editor 2> /dev/null`; chomp($editor); $editor = 'vi' if (!$editor); system("$editor $cfgFile"); } #------------------- # Config file reader #------------------- sub readCfg { my ($cfgFile) = @_; my $server = ''; my %cfg; open(CFG, "$cfgFile") || die "Please use \"run -e\" to config first.\n"; while(chomp($_ = )) { # ignore empty lines, comments and section headers next if (/(^\s*$|^\s*#|^\s*\[.*\]\s*$)/); my @a = split(/\s*=\s*/); my $val = $a[1]; # Eval unless the value is a string beginning with a digit $val = eval($a[1]) if ($a[1] !~ /^\d/ || $a[1] =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/); if ($a[0] eq "server") { $server = $a[1]; } else { $cfg{$a[0]} = ($@)? ($a[1]) : ($val); } } close(CFG); return($server, \%cfg); } __END__ =head1 NAME run - Script to submit job to PBS (Portable Batch System) as easy as possible =head1 SYNOPSIS run "command line" run [-h | -m | -v | -l | -e] -h help -m print the manual -v print the version number -l list the current config -e edit the config =head1 DESCRIPTION C is a small script applying C. It aims at making job submission to PBS quick and easy. It reads queueing options from the config file F<.runrc> in the home directory, generate job script and then submit to PBS. Current config can be listed by the C<-l> option. The C<-e> option is used to create or edit the config, using the editor specified by the EDITOR or VISUAL environment variables. To submit a command (say C<./a.out>), simply add C before it, e.g. C. Arguments (say C) of C can also be added behind, e.g. C. After submission, a job script will be generated. The default name is the command appended by ".sh". After the job is finished, two more files -- output and error file will be generated. They have names "[job name].o[job ID]" and "[job name].e[job ID]" respectively. =head1 CONFIG FILE Queueing options are declaring in F<.runrc> in the home directory. It has C<.ini>-style format, i.e. Parameter_1 = Value_1 Parameter_2 = Value_2 Spaces beside C<=> are optional. Also, lines beginning with "#" and blank lines are ignored. For example: # This is a sample config file for the "run" utility server = server01 queue = queue01 name = sample nodes = ['node01', 'node02'] ppn = 2 cput = 01:00:00 mem = 600mb To list the current configuration, use the C<-l> option. To create or edit the config file, use the C<-e> option. The default editor is C. To use other editor, please modify the environment variable C or C. For a sample config file, please see F in the module directory. =head1 EXAMPLES =over =item (1) Execute C<./a.out> run "./a.out" =item (2) Execute C<./a.out -a arg1 -b arg2 arg3> run "./a.out -a arg1 -b arg2 arg3" =item (3) Execute C<< ./a.out > /tmp/a.dat >> run "./a.out > /tmp/a.dat" =back =head1 REQUIREMENTS L =head1 BUGS Not known yet. Please email to kwmak@cpan.org for bug report or suggestions. =head1 AUTHOR(S) Ka-Wai Mak =head1 COPYRIGHT Copyright (c) 2006-2007 Ka-Wai Mak. All rights reserved. =head1 LICENSE This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut