2012-11-02 37 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