Unix Bash Script for running SAS

From sasCommunity
Jump to: navigation, search

Below is a bash shell script, for Unix, for running SAS program(s).

The main purpose of this script is for the log and print files to have date/time stamp as part of the file name. To me, a convenience, to keep track of multiple execution results. Secondary purpose is to send email w the SAS log.

It accepts one or more SAS programs then runs them sequentially (the default) or simultaneously (i.e. all at once). It also prompts user to supply autoexec, sysparm, sasuser, and user. If default settings for autoexec etc are acceptable, user can simply press ENTER to accept the default. If not, user can enter the desired values.

Copy and paste the following text into a file, say runsas, on Unix. Mark it as executable, by chmod +x runsas

Sample usage: runsas a1.sas a2.sas

#! /bin/bash
#
# Thu, 30Jul2009
# File name: hsM
#
#
# The SAS log or print files are appended w yyyymmdd-hhmmss, e.g.
# SASPgm-20090730-152025.log
# SASPgm-20090730-152025.lst
# where 20097030 is 30Jul2009.
#
#
# If you wish to change the default date/time format, search for
# dt=`date +%Y%m%d`
# tm=`date +%H%M%S`
# and change. E.g.
# dt=`date +%d%b%Y`
# produces date like 30Jul2009.
#
#
# Author: Hsiwei Yu
# Email: hsiwei_yu@yahoo.com
#

if [ $# -eq 0 ]; then
   echo There must be at least one parameter, the input SAS program file.
   exit 1
fi


TIMELIMIT=20
EMAILHOST=your-smtp-server-host-name
EMAILRECEIVER=recipient-email-address


if [ $# -ge 2 ]
   then
      echo \(S\|s\) for sequential, the default\; anything else is for immediately next.
      read -e -t $TIMELIMIT runMode
      # echo Received runMode=$runMode.
      runMode=${runMode:-s}
      # echo Enhanced runMode=$runMode.
fi

autoexec="-autoexec \"~/sas-programs/autoexec.sas\""
# echo autoexec default is $autoexec.
echo autoexec, default is -autoexec \"~/sas-programs/autoexec.sas\". Press enter to accept the default
echo or enter n or N for no autoexec or value like -autoexec \"/../..\" -echoauto.
read -e -t $TIMELIMIT autoexecU
# echo User input autoexec=$autoexecU.
if [ ${#autoexecU} -ge 1 ]
   then
      if echo $autoexecU | grep [nN] > /dev/null
         then
            autoexec=" "
            # echo User do NOT want autoexec at all.
         else
            autoexec="$autoexecU"
            # echo User input autoexec=$autoexec.
      fi
   # else
   #    echo autoexec UI is 0.
fi

echo SysParm, like %let name= value\; or simply empty for nothing
read -e -t $TIMELIMIT sysparm
# echo User input sysparm=$sysparm.
if [ ${#sysparm} -ge 1 ]
   then
      sysparm=" $sysparm "
      # echo User input userLibFolder=$userLibFolder.
fi

echo SASUser, like -rsasuser \(and/or\) sasuser \"/../..\" or simply empty for nothing
read -e -t $TIMELIMIT sasuser
# echo User input sasuser=$sasuser.
if [ ${#sasuser} -ge 1 ]
   then
      sasuser=" $sasuser "
      # echo User input userLibFolder=$userLibFolder.
fi
 
echo User lib folder, like -user \"/../..\" or simply empty for nothing
read -e -t $TIMELIMIT userLibFolder
if [ ${#userLibFolder} -ge 1 ]
   then
      userLibFolder=" $userLibFolder "
      # echo User input userLibFolder=$userLibFolder.
fi

echo Start to work on $# input files.
for file in $*
do
    rc=0
    if [ -e $file ]
       then
          dir=`dirname $file`/
          fileN=`basename $file`
          sasFile=${fileN%\.[sS][aA][sS]}
          dt=`date +%Y%m%d`
          tm=`date +%H%M%S`
          echo On $dt at $tm start w $file.
          if echo $runMode | grep [sS] > /dev/null
             then
         ( nohup sas $file \
          -sysparm "$sysparm %let dt=$dt; %let tm=$dt; %let username=$USER;" \
          $autoexec \
          -log $dir${sasFile}-${dt}-${tm}.log \
          -print $dir${sasFile}-${dt}-${tm}.lst \
          -emailhost $EMAILHOST \
          $userLibFolder $sasuser \
           > $dir${sasFile}-nohup-${dt}-${tm}.txt \
          2> $dir${sasFile}-nohup-err-${dt}-${tm}.txt
           # echo SAS job id=$!.
           rc=$?
           # echo RC=$rc.
           if [ -s $dir${sasFile}-${dt}-${tm}.lst ]
              then
                 # echo $dir${sasFile}-${dt}-${tm}.lst file to be printed.
                 cat $dir${sasFile}-${dt}-${tm}.log $dir${sasFile}-${dt}-${tm}.lst \
               | mailx -s "${sasFile} RC=$rc Log & Print Ran on $dt at $tm" $EMAILRECEIVER
              else
                 # echo $dir${sasFile}-${dt}-${tm}.lst file NOT printed.
                 mailx -s "${sasFile} RC=$rc Log Ran on $dt at $tm" $EMAILRECEIVER < $dir${sasFile}-${dt}-${tm}.log
           fi
         )
            else
         ( nohup sas $file \
          -sysparm "$sysparm %let dt=$dt; %let tm=$dt; %let username=$USER;" \
          $autoexec \
          -log $dir${sasFile}-${dt}-${tm}.log \
          -print $dir${sasFile}-${dt}-${tm}.lst \
          -emailhost $EMAILHOST \
          $userLibFolder $sasuser \
           > $dir${sasFile}-nohup-${dt}-${tm}.txt \
          2> $dir${sasFile}-nohup-err-${dt}-${tm}.txt
           # echo SAS job id=$!.
           rc=$?
           # echo RC=$rc.
           if [ -s $dir${sasFile}-${dt}-${tm}.lst ]
              then
                 # echo $dir${sasFile}-${dt}-${tm}.lst file to be printed.
                 cat $dir${sasFile}-${dt}-${tm}.log $dir${sasFile}-${dt}-${tm}.lst \
               | mailx -s "${sasFile} RC=$rc Log & Print Ran on $dt at $tm" $EMAILRECEIVER
              else
                 # echo $dir${sasFile}-${dt}-${tm}.lst file NOT printed.
                 mailx -s "${sasFile} RC=$rc Log Ran on $dt at $tm" $EMAILRECEIVER < $dir${sasFile}-${dt}-${tm}.log
           fi
         ) &
         fi
         dt3=`date +%Y%m%d`
         tm3=`date +%H%M%S`
         echo On $dt3 at $tm3 done w $file ready for the next.
      else
         echo Skip for $file NOT exist.
   fi
done