2019年5月22日 星期三

[Linux Shell Script] A script for parsing file, writing logs, archiving logs and taking args

We need a shell script to execute HTTP request on demand. This script shall read/parse text file and write/archive logs.
  • 3 sub functions
    1. get_script_dir : Get current folder path of this script
    2. echos : Write message to STDOut and log file
    3. archive_logs : Archive old logs to .tar
#!/bin/bash

# Functions
get_script_dir () 
{
 SOURCE="${BASH_SOURCE[0]}"
# While $SOURCE is a symlink, resolve it
 while [ -h "$SOURCE" ]; do
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$( readlink "$SOURCE" )"
# If $SOURCE was a relative symlink (so no "/" as prefix, need to resolve it relative to the symlink base directory
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
 done
 DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
 echo "$DIR/"
}

# DateFormat in log file : "[YYYY/MM/DD H:M:S]"
logDate=`date "+%Y%m%d"`
logFolder="$(get_script_dir)Logs/"

if [ ! -d $logFolder ]; then
 mkdir $logFolder
fi
logFile="${logFolder}CGI_Controller_${logDate}.log"

# Append STD out to file additionaly
echos ()
{
 logTime=`date "+%H:%M:%S"`
 builtin echo "[$logTime] $@" | tee -a "$logFile"
}

archive_logs()
{
 currentDate=`date "+%Y%m%d"`
 array=( $( ls ${logFolder} ) )
# Explicitly report array content.
 let i=0
 while (( ${#array[@]} > i )); do
 # echos "${i} ${array[i++]}"
 if [[ ${array[i]} == CGI_Controller_$currentDate* ]] || [[ ${array[i]} == zips ]]; then
  echos "The log is in the Current month, skipped it!"
 else
# Get target year and month for sufix of archived file name
  targetDate=`cut -d"_" -f 3 <<< "${array[i]}"`;
  targetDate=`cut -d"." -f 1 <<< $targetDate`;
  targetMonth="${targetDate:0:6}";
  zipFolder="$(get_script_dir)Logs/zips/"
  archivedFile="${zipFolder}Archived_${targetMonth}.tar.gz"
  if [ ! -d $zipFolder ]; then
   mkdir $zipFolder
  fi
  if [ -f "$archivedFile" ];then
   tar -rf $archivedFile --directory="${logFolder}" "${array[i]}" 
  else
   tar -cf $archivedFile --directory="${logFolder}" "${array[i]}" 
  fi
  echos "Archive file ${array[i]} to ${archivedFile}";
  rm "${logFolder}${array[i]}"
 fi
 ((i++))
 done
}
  • Main function
    1. Check if necessary files exist
    2. Check if parameter is valid
    3. Load setting file into an array
    4. Parsing settings and assemble CGI link
    5. Check server IP is UP
    6. Execute commands
# Main
# Check parameter number
if [ $# -ne 0 ]; then
 cmdI=$1
else
 echos "Parameter not found";
 exit 3
fi
# CMD array for each NVR
declare -a cmdArray

# Check if setting file existed
file="$(get_script_dir)config.txt"
if [ -f "$file" ];then
 echos "$file found";
else
 echos "$file not found, please create one";
 exit 4
fi

# Load file into array.
let i=0
while IFS=$'\n' read -r line_data; do
 cmdArray[i]="${line_data}"
((++i))
done < $file

# Roll back to item number
((--i))

if [ $i -le 0 ];then
 echos "No settings found in $file, please add CGI settings in this file. ([IP],[Path for Open],[Path for Close])";
 exit 5
fi

# Explicitly report array content.
#let i=0
#while (( ${#cmdArray[@]} > i )); do
# printf "${i} ${cmdArray[i++]}\n"
#done

# Make sure command number is less than settings number
if [ $cmdI -lt $i ]; then
 ip="$(cut -d';' -f1 <<<"${cmdArray[cmdI]}")"
 openPath="$(cut -d';' -f2 <<<"${cmdArray[cmdI]}")"
 closePath="$(cut -d';' -f3 <<<"${cmdArray[cmdI]}")"

 printf "${cmdI} ${cmdArray[cmdI]}\n"

 # Ping IP before executing it
 ping -c 1 -W 1 ${ip} &> /dev/null && result=0 || result=1

 if [ "${result}" == 0 ]; then
  echos "Server ${ip} is UP.";
 else
  echos "Server ${ip} is DOWN.";
  exit 6
 fi

 res="${logFolder}res"
 echos "http://${ip}${openPath}";
 wget -O $res "http://${ip}${openPath}";
 echos `cat $res`;
 # Delay 1 sec and then execute 2nd CGI command
 sleep 1
 echos "http://${ip}${closePath}";
 wget -O $res "http://${ip}${closePath}";
 echos `cat $res`;
 rm $res;
else
 echos "Parameter value is bigger than settings";
 exit 7
fi
archive_logs

沒有留言:

搜尋此網誌