I have a script which has a few functions inside it which the main body uses to execute. Now, I want to run this script on 3 remote unix machines. Which is the neatest way to do this ?
Most importantly, I don’t to write a second script for remote connection. Everything should be inside this one script.
I’ve tried heredoc with ssh, which is not working because of the big functions !
Code –
#!/bin/bash
# Year Month Day Related functions
# FUNCTIONS
# Find no. of days in a year
yeardays()
{
# argument check
if [ X$1 = X ]
then
read year
else
year=$1
fi
# Check for leap years
if [ `expr $year % 400` = 0 ]
then
echo 366
exit
fi
if [ `expr $year % 100` = 0 ]
then
echo 365
exit
fi
if [ `expr $year % 4` = 0 ]
then
echo 366
exit
fi
echo 365
}
# Find no. of days in a Month
monthdays()
{
# argument check
if [ X$1 = X ]
then
read ymd # year in yyyymmdd format
elif [ X$2 = X ]
then
ymd=$1
else
ymd=`expr \( $1 \* 10000 \) + \( $2 \* 100 \) + 1`
fi
year=`expr $ymd / 10000` ;
month=`expr \( $ymd % 10000 \) / 100` ;
case $month in
1|3|5|7|8|10|12) echo 31 ; exit ;;
4|6|9|11) echo 30 ; exit ;;
*) ;;
esac
# except for month 2, which depends on whether the year is a leap year
# Use yeardays to get the number of days in the year and return a value
# accordingly.
daysInYear=`yeardays $year`
case $daysInYear in
365) echo 28 ; exit ;;
366) echo 29 ; exit ;;
esac
}
ymd2yd() # convert from YYYYMMDD(gregorian) to YYYYDDD(julian)
{
# argument check
if [ X$1 = X ]
then
read date
else
date=$1
fi
year=`expr $date / 10000`
month=`expr \( $date % 10000 \) / 100`
days=`expr $date % 100`
count=1
while [ `expr $count \< $month` = 1 ]
do
daysInMonth=`monthdays $year $count`
days=`expr $days + $daysInMonth`
count=`expr $count + 1`
done
julian=`expr \( $year \* 1000 \) + $days`
echo $julian
}
yd2ymd() # convert from YYYYDDD(julian) to YYYYMMDD(gregorian)
{
# argument check
if [ X$1 = X ]
then
read date
else
date=$1
fi
year=`expr $date / 1000`
days=`expr $date % 1000`
month=1
while [ `expr $days \> 0` = 1 ]
do
daysInMonth=`monthdays $year $month`
days=`expr $days - $daysInMonth`
month=`expr $month + 1`
done
days=`expr $days \+ $daysInMonth`
month=`expr $month \- 1`
gregorian=`expr \( $year \* 10000 \) + \( $month \* 100 \) + $days`
echo $gregorian
}
ydadd() # Add/Subtract days to YYYYDDD format
{
# argument check
if [ X$2 = X ]
then
difference=$1
read yd # Read the YYYYDDD format date
else
yd=$1
difference=$2
fi
days=`expr $yd % 1000`
year=`expr $yd / 1000`
days=`expr $days + $difference`
daysInYear=`yeardays $year`
while [ `expr $days \> $daysInYear` = 1 ]
do
days=`expr $days - $daysInYear`
year=`expr $year + 1`
daysInYear=`yeardays $year`
done
while [ `expr $days \< 1` = 1 ]
do
year=`expr $year - 1`
daysInYear=`yeardays $year`
days=`expr $days + $daysInYear`
done
yd=`expr \( $year \* 1000 \) + $days` # Final date in YYYYDDD format
echo $yd
}
ymdadd() # Add/Subtract days to YYYYMMDD format
{
if [ X$2 = X ]
then
difference=$1
read ymd # Read YYYYMMDD format date
else
ymd=$1
difference=$2
fi
echo $ymd | ymd2yd | ydadd $difference | yd2ymd # Convert YYYYMMDD to YYYYDDD, perform date arithmetic, then revert to YYYYMMDD format
}
daysLeft() # Calculate days between two dates in YYYYMMDD format
{
# argument check
if [ X$1 = X ]
then
read ymd1 # First date in YYYYMMDD format
read ymd2 # Second date in YYYYMMDD format
elif [ X$2 = X ]
then
ymd1=$1
read ymd2
else
ymd1=$1
ymd2=$2
fi
year1=`expr $ymd1 / 10000`
month1=`expr \( $ymd1 % 10000 \) / 100`
day1=`expr $ymd1 % 100`
year2=`expr $ymd2 / 10000`
month2=`expr \( $ymd2 % 10000 \) / 100`
day2=`expr $ymd2 % 100`
daysm1=`monthdays $year1 $month1`
days=`expr $daysm1 - $day1`
month1=`expr $month1 + 1`
while [ `expr $month1 \<= 12` = 1 ]
do
daysm1=`monthdays $year1 $month1`
days=`expr $days + $daysm1`
month1=`expr $month1 + 1`
done
x=1
while [ `expr $x \< $month2` = 1 ]
do
daysm2=`monthdays $year2 $x`
days=`expr $days + $daysm2`
x=`expr $x + 1`
done
days=`expr $days + $day2`
echo $days
}
# MAIN BODY
# Connect to different Servers
declare -a SERVER=('server1' 'server2' 'server3')
remoteUser=abc
serverNumbers=${#SERVER[@]}
count=0
while [ `expr $count \< $serverNumbers` = 1 ]
do
# Connect to server
ssh -T -q $remoteUser@${SERVER[count]} <<-"END_TEXT"
VALUE=`cat /home/cognos/cognos/c8/configuration/cogstartup.xml | grep -i xsd:long | head -1 | cut -d">" -f2 | sed 's/[:/<|crn:value]*//g'`
VALUE_BACKUP=$VALUE
let 'VALUE -= 30'
let 'VALUE *= 86400'
RESULT1=`perl -e '@stats = stat("/home/cognos/cognos/c8/configuration/signkeypair"); print ((time - $stats[9]) < "$VALUE");'`
RESULT2=`perl -e '@stats = stat("/home/cognos/cognos/c8/configuration/encryptkeypair"); print ((time - $stats[9]) < "$VALUE");'`
RESULT3=`perl -e '@stats = stat("/home/cognos/cognos/c8/configuration/caSerial"); print ((time - $stats[9]) < "$VALUE");'`
while [ "$RESULT1" -o "$RESULT2" -o "$RESULT3" ]
do
echo "Sending mail."
# Calculate days left
CURRENT_DATE=`date +"%Y-%m-%d" | sed 's/-//g'`
CREATION_DATE=`ls -logE /home/cognos/cognos/c8/configuration/ | grep -i signkeypair | awk '{print $4}' | sed 's/-//g'`
EXPIRY_DATE=`ymdadd $CREATION_DATE $VALUE_BACKUP`
DAYS_LEFT=`daysLeft $CURRENT_DATE $EXPIRY_DATE`
# Identify environment from hostname - DEV/UAT/PRD
LOCALHOST=`hostname`
ENVIRONMENT_TYPE=`echo $LOCALHOST | perl -ne '~m/.*([a-zA-Z]{3})[0-9]*$/; print $1;'|tr '[a-z]' '[A-Z]'`
# Identify process - FormPF/GoReporting
if (echo $LOCALHOST | grep -i cfp >/dev/null) then
PROCESS="FormPF"
else
PROCESS="GoReporting"
fi
# Add details to mail body
echo "The key was created on `ls -log /home/cognos/cognos/c8/configuration/ | grep -i signkeypair | awk '{print $4,$5,$6}'`, and was set to expire after $VALUE_BACKUP days." > mail.txt
echo "Key expires in $DAYS_LEFT days !!" >> mail.txt
echo " " >> mail.txt
echo "The server is-" >> mail.txt
hostname >> mail.txt
echo " " >> mail.txt
echo "Status of folders/files-" >> mail.txt
echo " " >> mail.txt
ls -log /home/cognos/cognos/c8/configuration/ | grep -i signkeypair | awk '{print $4,$5,$6,$7}' >> mail.txt
ls -log /home/cognos/cognos/c8/configuration/ | grep -i encryptkeypair | awk '{print $4,$5,$6,$7}' >> mail.txt
ls -log /home/cognos/cognos/c8/configuration/ | grep -i caSerial | awk '{print $4,$5,$6,$7}' >> mail.txt
echo " " >> mail.txt
echo "To reactive key, please restart the server at weekend with below options:" >> mail.txt
echo " " >> mail.txt
echo "/home/cognos/etc/restartAllServers.sh -cdsk" >> mail.txt
# Send warning mail !!
SUBJECT="!! ($ENVIRONMENT_TYPE) $PROCESS ($LOCALHOST) Cognos CSK(Common Symmetric Key) Expiry !!"
EMAIL="xyz@abc.com"
cat mail.txt | mailx -s "$SUBJECT" "$EMAIL"
rm mail.txt
break
done
logout
END_TEXT
count=`expr $count + 1`
done
exit 0
Move the functions inside the heredoc. It may require some changes to the code structure but it will work.
You’ll get the hostname and date on the remote server, not yours. Works. Stupid example, but proof of concept.