2012-11-02 34 views
0

我有一個腳本,裏面有一些主體用來執行的函數。現在,我想在3個遠程unix機器上運行這個腳本。這是最好的方法嗎? 最重要的是,我不寫遠程連接的第二個腳本。一切都應該在這一個腳本里面。使用這裏面的函數文件

我試過heredoc與SSH,這是不工作,因爲大功能!

碼 -

#!/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 [email protected]${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="[email protected]" 
      cat mail.txt | mailx -s "$SUBJECT" "$EMAIL" 
     rm mail.txt 
      break 
    done 
    logout 
    END_TEXT 
    count=`expr $count + 1` 
done 
exit 0 
+0

不錯的腳本,但您如何期待您遠程執行腳本(通過ssh)來查找您定義的函數。您可以將它們安裝在遠程機器上,或者像腳本的主體一樣將它們「通過網絡傳送」。請注意,ssh可以傳遞內聯命令的大小有一定的限制,並且您可能會遇到在錯誤時間進行變量擴展的問題,這需要引用特殊字符和轉義字符等。祝您好運。 – shellter

+0

@shellter我試着發送整個腳本'over-the-wire',徒勞無功。是否可以在腳本中使用scp而不進入無限循環? –

+0

'if [$(expr ...)= 0];那麼...'讓我的眼睛受傷。相反,使用:'如果expr ...>/dev/null;然後......' –

回答

0

移動的定界符文本的功能。它可能需要對代碼結構進行一些更改,但它會起作用。

ssh app01.datacentre.private <<EOD 
hostdatefunc() { 
echo \$(hostname) \$(date) 
} 
hostdatefunc 
EOD 

你會得到遠程服務器的主機名和日期,不是你的。作品。愚蠢的例子,但概念證明。

+0

heredoc可以包含函數嗎?我想我必須把這些函數放入變量中,然後放入heredoc。你在談論什麼樣的改變? –

+0

@kaustavdatta我的例子工程,所以功能工作。當然,您需要知道遠程主機上正在使用哪種外殼。至於變化 - 嗯,我沒有詳細閱讀你的腳本 - 如果這些函數在heredoc之外以及它內部使用,那麼你必須將它們複製到heredoc中,而不是移動它們。 – itsbruce

+1

您必須引用'EOD',否則您將獲得本地主機名和日期。 – choroba