#!/bin/sh # # Run a Perl script for iRODS. # # Usage is: # ./runPerlScript [options] # # This shell script starts a Perl script set on the command-line. # It looks for Perl on the user's path and in standard locations # on UNIX and Windows Cygwin, then invokes Perl with the given # arguments. # # Options are: # --script script the name of the Perl script to run # --dir directory the name of the directory to run from # # All other options are passed to the Perl script unchanged. # # # @brief Print error messages in red. # # The given text is printed in red using standard xterm/vt100 # escape codes to set the text color. # # @param text # the text to print # printError( ) { echo "$1" } # # @brief Find the path to Perl on this system. # # The system is searched for the Perl executable with the highest # version number. When found, PERL_PATH is set. Otherwise # PERL_PATH is the empty string. # PERLPATH="" findPerl( ) { # On many systems there is just one Perl installed. But # sometimes a system may have one version that came with # the OS in /usr/bin, and a more recent version installed # by the sysadmin in /usr/local. We'd prefer to use the # more recent version. # Below we build a list of all Perls found in standard # locations. Each one is written to a temporary results # file, one per row. Each row starts with the version # number reported by that Perl, followed by the path to it. # When we're done searching, if there is only one entry # in the file, we use it. Otherwise the file is sorted # numerically and we use the entry with the highest # version number. RESULTSFILE="/tmp/irods_$$.txt" # While "perl -v" reports version information for the program, # this is hard to parse. Instead, we use the following # one line program: PERLPROG="'print $]'" # Check standard top-level directories, such as /, /opt, # /sw, and /cygwin. # # Then look in all the standard places. # UNIX standard directories: # /bin /sbin /usr/bin /usr/sbin # /usr/local /usr/local/bin # /usr/share /usr/share/bin # Solaris added directories: # /usr/ucb # MacPorts directories: # /opt/bin /opt/sbin /opt/usr/bin /opt/usr/sbin # /opt/usr/local/bin /opt/usr/share/bin # Fink directories: # /sw/bin /sw/sbin /sw/usr/bin /sw/usr/sbin /sw/usr/local/bin # /sw/usr/share/bin # Cygwin directories: # /cygwin/bin /cygwin/sbin /cygwin/usr/bin /cygwin/usr/sbin # /cygwin/usr/local/bin /cygwin/usr/share/bin foundany="0" # # First, we include the user's prefered perl, in case it's the best. # This is needed at NMI B&T for example, where the path is adjusted to # select preferred versions of commands. # foundWhich=`which perl` if [ $? -eq 0 ]; then PERL_PATH="$foundWhich" # It's a file. Runnable? $PERL_PATH -v > /dev/null 2>&1 if [ $? -eq 0 ]; then # Record working perl PERL_VERSION=`echo 'print $]' | $PERL_PATH` echo "$PERL_VERSION $PERL_PATH" >> $RESULTSFILE foundany="1" fi fi # # Now we check other locations for more recent Perl's. # for prefix in "/" "/opt" "/sw" "/cygwin"; do if [ ! -d $prefix ]; then continue # No such prefix directory fi # Look in standard UNIX directories for dir in "bin" "sbin" "usr/bin" "usr/sbin" "usr/udb" \ "usr/local" "usr/local/bin" "usr/share" "usr/share/bin" ; do if [ ! -d $prefix/$dir ]; then continue # No such directory fi # Is $prefix/$dir/perl there? PERL_PATH="$prefix/$dir/perl" if [ -f $PERL_PATH ]; then # It's a file. Runnable? $PERL_PATH -v > /dev/null 2>&1 if [ $? -eq 0 ]; then # Record working perl PERL_VERSION=`echo 'print $]' | $PERL_PATH` echo "$PERL_VERSION $PERL_PATH" >> $RESULTSFILE foundany="1" fi fi # Get all other perls ending with a number. Often # these are separate older versions of Perl, or # directories for different Perl versions. foundLocal=`ls -d $prefix/$dir/perl[0-9]* 2> /dev/null` if [ $? -ne 0 ]; then continue # No perl in directory fi for found in $foundLocal; do # Is it a file? PERL_PATH="$found" if [ -f $PERL_PATH ]; then # It's a file. Runnable? $PERL_PATH -v > /dev/null 2>&1 if [ $? -eq 0 ]; then # Record working perl PERL_VERSION=`echo 'print $]' | $PERL_PATH` echo "$PERL_VERSION $PERL_PATH" >> $RESULTSFILE foundany="1" fi continue fi # Is it a directory? if [ -d $PERL_PATH ]; then # It's a directory. Contains 'perl'? PERL_PATH="$found/perl" if [ -f $PERL_PATH ]; then # It's a file. Runnable? $PERL_PATH -v > /dev/null 2>&1 if [ $? -eq 0 ]; then # Record working perl PERL_VERSION=`echo 'print $]' | $PERL_PATH` echo "$PERL_VERSION $PERL_PATH" >> $RESULTSFILE foundany="1" fi fi # Contains 'bin/perl'? PERL_PATH="$found/bin/perl" if [ -f $PERL_PATH ]; then # It's a file. Runnable? $PERL_PATH -v > /dev/null 2>&1 if [ $? -eq 0 ]; then # Record working perl PERL_VERSION=`echo 'print $]' | $PERL_PATH` echo "$PERL_VERSION $PERL_PATH" >> $RESULTSFILE foundany="1" fi fi continue fi done done done # Were any found? if [ "$foundany" -ne "0" ]; then # Sort the results numerically. SORTEDRESULTSFILE="/tmp/irods_$$_2.txt" sort -rn $RESULTSFILE > $SORTEDRESULTSFILE rm -f $RESULTSFILE # Take the first one. Use this loop approach # to get the 2nd word in the file instead of # using awk so that we don't require that awk # be installed on this system. gotfirst="0" for word in `cat $SORTEDRESULTSFILE`; do if [ "$gotfirst" -eq "0" ]; then gotfirst="1" continue fi PERL_PATH="$word" rm -f $SORTEDRESULTSFILE return done PERL_PATH="" rm -f $SORTEDRESULTSFILE return fi rm -f $RESULTSFILE # Nope. None of the standard directories had it. # Perhaps the user has it on their path? # Is Perl on the user's path? perl -v > /dev/null 2>&1 if [ $? -eq 0 ]; then # Yup. Use it. PERL_PATH="perl" return fi # Can 'which' find it? Technically, this just searches the user's # path, so it should be no better than the above. However, it also # looks at aliases and resets the path to that found in the user's # .cshrc, so it can un-do changes caused to the user's current # environment. It's worth a try. foundWhich=`which perl` if [ $? -eq 0 ]; then # Yup. Use it. PERL_PATH="$foundWhich" return fi # Nothing. PERL_PATH="" return } # Parse the command-line and separate out arguments for # this script, and those for the Perl script to be invoked. PERL_SCRIPT="" PERL_RUN_DIRECTORY="." PERL_SCRIPT_ARGUMENTS="" THIS_SCRIPT="$0" THIS_COMMAND_LINE="$*" while [ $# -ne 0 ]; do case $1 in --script) shift PERL_SCRIPT=$1 ;; --dir) shift PERL_RUN_DIRECTORY=$1 ;; *) PERL_SCRIPT_ARGUMENTS="$PERL_SCRIPT_ARGUMENTS $1" ;; esac shift done # Make sure the script and directory exist if [ ! -d "$PERL_RUN_DIRECTORY" ]; then printError "Programmer error:" printError " The '$PERL_RUN_DIRECTORY' directory does not exist." printError " " printError " The '$THIS_SCRIPT' script was probably invoked with a bad" printError " --dir argument." printError " Command line: $THIS_SCRIPT $THIS_COMMAND_LINE" printError " " printError "Abort." exit 1 fi if [ ! -f "$PERL_SCRIPT" ]; then if [ ! -f "$PERL_RUN_DIRECTORY/$PERL_SCRIPT" ]; then printError "Programmer error:" printError " The '$PERL_SCRIPT' Perl script does not exist." printError " " printError " The '$THIS_SCRIPT' script was probably invoked with a bad" printError " --script argument." printError " Command line: $THIS_SCRIPT $THIS_COMMAND_LINE" printError " " printError "Abort." exit 1 fi fi # Find perl findPerl if [ "$PERL_PATH" = "" ]; then printError "Configuration problem:" printError " This script requires Perl, but Perl cannot be found on" printError " your system. You can get the latest version of Perl from:" printError " http://perl.org/" printError " " printError "Abort. Please re-run this script after installing Perl." exit 1 fi # Run the script cd $PERL_RUN_DIRECTORY $PERL_PATH $PERL_SCRIPT $PERL_SCRIPT_ARGUMENTS ExitCode="$?" exit $ExitCode