notice the FTP_PUT_RETVAL. There are two echo commands, the first one shows a value of '0'. The second one shows no value at all. I am running this inside a nightly cron. BASH is GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
My script tells me that the ftp upload was unsuccessful, because FTP_PUT_RETVAL contains no value!
Why is this occuring? How can I change this? What have I done wrong?
#!/bin/sh
#
# Filename: rh5-manager-cron.sh
#
# Purpose: Runs backup.cron, and FTP uploads backup to Linux4
#
# Usage: the program is run with no arguments. This program is
# intended to run from manager cron, and redirection is handled inside the cron
# e.g. 00 1 * * * /u2/app/lbin/rh5-manager-cron.sh > /tmp/log/rh5-manager-cron.log 2>&1
trap signalCaught ABRT EXIT HUP INT PIPE TERM QUIT
signalCaught () {
for file in $FTP_LOG_FILE $TMPF; do
$BIN_HOME/rm_file $TMPF
done
exit
}
if [[ ! -r /u2/conf/ctrl/lettus.sh || ! -r /u2/app/lbin/fsh_sh_lib ]]; then
printf "Cannot source environment.\n" >&2
exit 1
fi
. /u2/conf/ctrl/lettus.sh
. /u2/app/lbin/fsh_sh_lib
#-------------------------------------------------------
# Variables
#-------------------------------------------------------
PRG=${0##*/}
FTPUSER=dummy
FTPPASS=dummy
FTPHOST=192.168.0.3
BACKUPDIR=/backup
FTPBACKUPNAME=Redhat5Backup.tgz
FTPBACKUPFILE=$BACKUPDIR/$FTPBACKUPNAME
LOGDIR=/tmp/log
FTP_LOG_FILE=$LOGDIR/Redhat5FTP.log
SENDLOGS=$C/sendlogs.dat
ZOOT_XML=$C/zoot.xml
TMPF=`mktemp` || exit 1
#-------------------------------------------------------
# Sanity
#-------------------------------------------------------
if ! isValidUser root manager; then
printf "$PRG: Must be run as user 'root' or user 'manager'.\n" >&2
exit 1
fi
if [[ ! -d $BACKUPDIR ]]; then
logger "$PRG: $BACKUPDIR: Not a valid directory" >&2
exit 1
fi
if [[ ! -d $LOGDIR ]]; then
logger "$PRG: $LOGDIR: Not a valid directory" >&2
exit 1
fi
if [[ ! -r $SENDLOGS || ! -r $ZOOT_XML ]]; then
logger "$PRG: E-mail: Files are not readable: $SENDLOGS, $ZOOT_XML" >&2
exit 1
fi
if ! which lftp >/dev/null 2>&1; then
logger "$PRG: lftp: command not found" >&2
exit 1
fi
# e-mail
EMAIL_SUBJECT="Redhat5 FTP PUT"
EMAIL_TO=$(email_to $SENDLOGS)
EMAIL_FROM=$(email_from $ZOOT_XML)
# ftp binary
LFTP_BIN=$(which lftp 2>/dev/null)
#-------------------------------------------------------
# Functions
#-------------------------------------------------------
# calls lftp to upload a file to server non-interactively
ftp_put() {
$LFTP_BIN $LFTP_DEBUG -u ${FTPUSER},${FTPPASS} $FTPHOST <<-EOF
put $FTPBACKUPFILE
pwd
ls $FTPBACKUPNAME
quit
EOF
#^^^^^^^^^^^ leave the above indentation alone
}
main() {
# Backup, and send manager logs
logger "Running backup.cron..."
echo
backup.cron
BACKUP_CRON_RETVAL=$?
logger "Running fsh_sendlogs..."
echo
$SH_HOME/fsh_sendlogs 1
# show ls listing
logger "Here comes a directory listing..."
echo
/bin/ls -l /backup/Redhat5Backup.tgz
echo
# ftp upload
logger "Running ftp upload..."
echo
ftp_put
FTP_PUT_RETVAL=$?
echo " -- debug: Line ${LINENO:-}: FTP_PUT_RETVAL=${FTP_PUT_RETVAL:-}"
}
checkSuccess() {
if [[ "$BACKUP_CRON_RETVAL" -eq 0 ]]; then
echo "Backup was successful."
echo
echo "*********************************"
echo " OK: Backup was successful."
echo "*********************************"
echo
else
echo "ERROR: Backup FAILED! "
echo
echo "*********************************"
echo " ERROR: Backup FAILED! "
echo "*********************************"
echo
fi
echo " -- debug: Line ${LINENO:-}: FTP_PUT_RETVAL=${FTP_PUT_RETVAL:-}"
if [ "$FTP_PUT_RETVAL" -eq 0 ]; then
echo "lftp: ftp file upload complete."
echo
echo "*********************************"
echo " OK: ftp file upload complete."
echo "*********************************"
echo
else
echo "lftp: error ftp file upload not successful."
echo
echo "*********************************"
echo " ERROR: file upload"
echo " NOT successful."
echo "*********************************"
echo
fi
}
email_logs() {
if [[ -z "$EMAIL_FROM" || -z $EMAIL_TO || -z $EMAIL_SUBJECT || ! -r $FTP_LOG_FILE ]]; then
logger "$PRG: One of the variables is not correctly configured" >&2
exit 1
fi
fsh_mail -r "${EMAIL_TO}" -F "${EMAIL_FROM}" -s "${EMAIL_SUBJECT}" -t "${FTP_LOG_FILE}"
return
}
#----------------------------------------------------------------------
# Main Program
#----------------------------------------------------------------------
main | tee $FTP_LOG_FILE
checkSuccess | tee -a $FTP_LOG_FILE $TMPF
cat $FTP_LOG_FILE >> $TMPF
# E-mail ftp log file
logger "Emailing ftp logfile"
echo
email_logs
#eof
The problem is that you are using:
main | tee $FTP_LOG_FILE
checkSuccess | tee -a $FTP_LOG_FILE $TMPF
Because of the piping, the work done in main is done in a sub-shell, and a sub-shell cannot set variables in the parent shell. So, when checkSuccess (which is also run in a sub-shell) goes to look at the results, it sees what was in the parent shell (nothing), rather than what was set in the main function in a sub-shell.
If you dropped the piping, it would start to work.
More reliably, put the call to checkSuccess into the main function. Or use one or the other of these two notations:
{ main; checkSuccess; } | tee $FTP_LOG_FILE $TMPF
( main; checkSuccess ) | tee $FTP_LOG_FILE $TMPF
Note that the { ... } notation requires a semi-colon after the second function which the ( ... ) notation does not require. However, there is one less process involved in the { ... } mechanism, not that it is going to make any measurable difference to the overall performance of this (the FTP time will dominate).
Related
This is the code for wal archive clean up in postgresql. I am passing archive path and age before when wal needs to be cleaned up. Its a wrapper scrip but somehow its not working. Whenever I pass arguments it throws first message for passing correct parameters even though I am giving correct one.
#!/bin/bash
if [ "$#" -ne 2 ]; then
echo -e "This script helps in cleaning up archived log files in postgres. Give the command with parameters in order\t
sh walarchivecleanup.sh -p archivepath -a age (days) "
echo "Usage : walarchivecleanup.sh -p archivepath -a age"
echo -e "\t -p <value> -- Path to the archived WAL logs (e.g. /pg_data/pg_xlog/archive)"
echo -e "\t -a <value> -- Age of archived logs to keep (days), anything older will be deleted"
exit 1
else
echo -e "Do Nothing"
fi
archivepath=$1
age=$2
##########################################################
while getopts "p:a" opt;
do
case ${opt} in
p) archivepath=${OPTARG};;
a) age=${OPTARG};;
\? )
echo "Usage: sh walarchivecleanup.sh -p archivepath -a age (days) "
;;
esac
done
###############################################################
if [[ -z $archivepath ]]; then echo "Error: Missing archivepath"; exit 1; fi
if [[ -z $age ]]; then echo "Error: Age (-a) must be given"; exit 1; fi
if ! [[ -d $archivepath ]]; then
echo "Error: archivepath not found"; exit 1
else
cmd_path=$archivepath
fi
if [[ -n $archivecleanup ]]; then
if ! [[ -x $archivecleanup ]]; then
echo "Error: Command $archivecleanup not found or no permission to execute"; exit 1;
else
cmd_command="$archivecleanup"
fi
else
if ! `which pg_archivecleanup 1>/dev/null`; then echo "Error: Command pg_archivecleanup not found"; exit 1; fi
cmd_command="pg_archivecleanup"
fi
if [[ -n $age ]]; then
cmd_file="$(find ${archivepath}/ -type f -mtime +${age} -printf "%C# %f\n" |sort -n | tail -n 1 | awk '{print $NF}')"
else
cmd_file="$archivefile"
fi
execute="$cmd_command $cmd_path $cmd_file"
`$execute`
exit $?
echo "Unknown Error - Should never reach this part"
exit 1
I might be blind, but I can't find the errors my script got, maybe you guys got better eyes than me :). I use a busybox compiled linux on a embedded system, Kernel 4.18.0. I found the base script here: Gist-Template
the following error is at "start":
./daemon: line 195: arithmetic syntax error
when I try "stop" these messages appear, but i dont see a unknown operand at line 0:
sh: 0: unknown operand
* Stopping Monitoring
my script:
#!/bin/sh
daemonName="Monitoring"
pidDir="."
pidFile="$pidDir/$daemonName.pid"
pidFile="$daemonName.pid"
logDir="."
# To use a dated log file.
# logFile="$logDir/$daemonName-"`date +"%Y-%m-%d"`".log"
# To use a regular log file.
logFile="$logDir/$daemonName.log"
# Log maxsize in KB
logMaxSize=1024 # 1mb
runInterval=300 # In seconds
doCommands() {
# This is where you put all the commands for the daemon.
echo "Running commands."
}
############################################################
# Below are the command functions
############################################################
hw_temp() {
cpu_temp=$(sensors|grep CPU|awk '{print $3}'|awk '{print ($0-int($0)<0.499)?int($0):int($0)+1}')
env_temp=$(sensors|grep ENV|awk '{print $3}'|awk '{print ($0-int($0)<0.499)?int($0):int($0)+1}')
pcb_temp=$(sensors|grep PCB|awk '{print $3}'|awk '{print ($0-int($0)<0.499)?int($0):int($0)+1}')
echo "$cpu_temp $env_temp $pcb_temp" >> /opt/monitoring/bla
}
############################################################
# Below is the skeleton functionality of the daemon.
############################################################
myPid=`echo $$`
setupDaemon() {
# Make sure that the directories work.
if [ ! -d "$pidDir" ]; then
mkdir "$pidDir"
fi
if [ ! -d "$logDir" ]; then
mkdir "$logDir"
fi
if [ ! -f "$logFile" ]; then
touch "$logFile"
else
# Check to see if we need to rotate the logs.
size=$((`ls -l "$logFile" | cut -d " " -f 8`/1024))
if [[ $size -gt $logMaxSize ]]; then
mv $logFile "$logFile.old"
touch "$logFile"
fi
fi
}
startDaemon() {
# Start the daemon.
setupDaemon # Make sure the directories are there.
if [[ `checkDaemon` = 1 ]]; then
echo " * \033[31;5;148mError\033[39m: $daemonName is already running."
exit 1
fi
echo " * Starting $daemonName with PID: $myPid."
echo "$myPid" > "$pidFile"
log '*** '`date +"%Y-%m-%d"`": Starting up $daemonName."
# Start the loop.
loop
}
stopDaemon() {
# Stop the daemon.
if [[ `checkDaemon` -eq 0 ]]; then
echo " * \033[31;5;148mError\033[39m: $daemonName is not running."
exit 1
fi
echo " * Stopping $daemonName"
log '*** '`date +"%Y-%m-%d"`": $daemonName stopped."
if [[ ! -z `cat $pidFile` ]]; then
kill -9 `cat "$pidFile"` &> /dev/null
fi
}
statusDaemon() {
# Query and return whether the daemon is running.
if [[ `checkDaemon` -eq 1 ]]; then
echo " * $daemonName is running."
else
echo " * $daemonName isn't running."
fi
exit 0
}
restartDaemon() {
# Restart the daemon.
if [[ `checkDaemon` = 0 ]]; then
# Can't restart it if it isn't running.
echo "$daemonName isn't running."
exit 1
fi
stopDaemon
startDaemon
}
checkDaemon() {
# Check to see if the daemon is running.
# This is a different function than statusDaemon
# so that we can use it other functions.
if [ -z "$oldPid" ]; then
return 0
elif [[ `ps aux | grep "$oldPid" | grep "$daemonName" | grep -v grep` > /dev/null ]]; then
if [ -f "$pidFile" ]; then
if [[ `cat "$pidFile"` = "$oldPid" ]]; then
# Daemon is running.
# echo 1
return 1
else
# Daemon isn't running.
return 0
fi
fi
elif [[ `ps aux | grep "$daemonName" | grep -v grep | grep -v "$myPid" | grep -v "0:00.00"` > /dev/null ]]; then
# Daemon is running but without the correct PID. Restart it.
log '*** '`date +"%Y-%m-%d"`": $daemonName running with invalid PID; restarting."
restartDaemon
return 1
else
# Daemon not running.
return 0
fi
return 1
}
loop() {
# This is the loop.
now=`date +%s`
if [ -z $last ]; then
last=`date +%s`
fi
# Do everything you need the daemon to do.
doCommands
# Check to see how long we actually need to sleep for. If we want this to run
# once a minute and it's taken more than a minute, then we should just run it
# anyway.
last=`date +%s`
# Set the sleep interval
if [[ ! $((now-last+runInterval+1)) -lt $((runInterval)) ]]; then
sleep $((now-last+runInterval))
fi
# Startover
loop
}
log() {
# Generic log function.
echo "$1" >> "$logFile"
}
###############################################################
# Parse the command.
###############################################################
if [ -f "$pidFile" ]; then
oldPid=`cat "$pidFile"`
fi
checkDaemon
case "$1" in
start)
startDaemon
;;
stop)
stopDaemon
;;
status)
statusDaemon
;;
restart)
restartDaemon
;;
*)
echo "Error: usage $0 { start | stop | restart | status }"
exit 1
esac
exit 0
I have many javascript files in my solaris server which have some debug, print and trace statements which I want to comment. There are hundreds of file like this.
I have found a script to do this but the problem is the script is removing the urhk_b2k_printRepos statement instead of commenting it. The script is as below:
if [ $# -ne 2 ]
then
echo "usage: prdel <script file name> <directory in which scripts are present>"
exit 1
fi
file=$1
dir=$2
if [ ! -s ${file} ]
then
echo "script file ${file} either does not exist or is empty (zero bytes)"
echo "Exiting..."
exit 1
fi
if [ ! -d ${dir} ]
then
echo "Invalid directory ${dir} entered"
echo "Exiting..."
exit 1
fi
cordir="./corrected"
prlogdir="./prlog"
if [ -d ${cordir} ]
then
echo "The corrected directory exist in the path, Please remove and run the tool again"
echo "Exiting..."
exit 1
else
mkdir ${cordir}
fi
if [ -d ${prlogdir} ]
then
echo "The prlog directory exist in the path, Please remove and run the tool again"
echo "Exiting..."
exit 1
else
mkdir ${prlogdir}
fi
errFile="$prlogdir/scr_err.rpt"
sucFile="$prlogdir/scr_suc.rpt"
Lines=`wc -l $file`
cntr=1
while [ $cntr -le $Lines ]
do
src=`head -$cntr $file|tail -1`
echo "$cntr. Processing $src...."
srcPath="${dir}/${src}"
if [ ! -s ${srcPath} ]
then
echo "Script file ${src} does not exist in the path given" >> ${errFile}
else
cp $srcPath $cordir/$src.tmp
srctemp="$cordir/$src.tmp"
srccor="$cordir/$src.corrected"
printcnt=`grep -ci "^[ ]*print" $srctemp`
if [ $printcnt -ne 0 ]
then
cat $srctemp|sed 's/^[ ]*[ ]*print[ ]*(/#print(/'|sed 's/^[ ]*[ ]*PRINT[ ]*(/#PRINT(/' > $srccor
mv $srccor $srctemp
fi
prreposcnt=`grep -ci "printrepos" $srctemp`
if [ $prreposcnt -ne 0 ]
then
cat $srctemp|sed 's/^.*urhk_b2k_printRepos.*/#Printrepos statement removed/'|sed 's/^.*urhk_B2k_PrintRepos.*/#Printrepos statement removed/'|sed 's/^.*urhk_B2k_printRepos.*/#Printrepos statement removed/'|sed 's/^.*urhk_b2k_PrintRepos.*/#Printrepos statement removed/' > $srccor
else
cp $srctemp $srccor
fi
echo "Script file $src correction is done" >> ${sucFile}
rm $srctemp
diff $srcPath $srccor >> $prlogdir/$src.diff.rpt
fi
cntr=`expr $cntr + 1`
done
echo "done"
I am completely new to shell scripting. Can anyone help me to modify this script to comment "urhk_b2k_printRepos" lines and also comment "TRACE ON" lines.
An array holds the files accessed, and the archive files are split into smaller sizes in preparation for online backup. I am attempting to retrieve the exit code for each iteration through the loop of the split command. However, it is returning Exit Code 1, yet it says that the operation was successful. Why?
#!/bin/bash
declare -a SplitDirs
declare -a CFiles
CDIR=/mnt/Net_Pics/Working/Compressed/
SDIR=/mnt/Net_Pics/Working/Split/
Err=/mnt/Net_Pics/Working
SplitDirs=(`ls -l "$CDIR" --time-style="long-iso" | egrep '^d' | awk '{print $8}'`)
for dir in "${SplitDirs[#]}"
do
if [ ! -d "$SDIR""$dir" ]; then
mkdir "$SDIR""$dir"
else continue
fi
CFiles=(`ls -l "$CDIR$dir" --time-style="long-iso" | awk '{print $8}'`)
for f in "${CFiles[#]}"
do
if [ ! -e "$SDIR""$dir"/"$f" ]; then
split -d -a 4 -b 1992295 "$CDIR""$dir"/"$f" "$SDIR""$dir"/"$f" --verbose
if [[ "$?" == 1 ]]
then
rm -rf "$SDIR""$dir" && echo "$SDIR""$dir" "Removed due to Error code" "$?""." "Testing Archives and Retrying..." 2>&1 | tee "$Err"/Split_Err.log
7z t "$CDIR""$dir"/"$f" >> tee stdout.log 2>> "$Err"/"$dir"/7z_Err.log >&2
mkdir "$SDIR""$dir" && split -d -a 4 -b 1992295 "$CDIR""$dir"/"$f" "$SDIR""$dir"/"$f" --verbose
if [[ "$?" == 1 ]]
then
rm -rf "$SDIR""$dir" && echo "$SDIR""$dir" "Removed a second time due to Error code "$?". Skipping..." 2>&1 | tee "$Err"/Split_Err.log
continue
else
echo "Split Success:" "$SDIR""$dir"/"$f" "ended with Exit status" "$?" && continue
fi
else
echo "Split Success:" "$SDIR""$dir" "ended with Exit status" "$?" && continue
fi
else
echo "$SDIR""$dir"/"$f" "Exists... Skipping Operation" 2>&1 | tee "$Err"/"$dir"/Split_Err.log
continue
fi
done
(The echo piping in a previous revision of the question was misplaced code, and thank you for pointing that out. The exit code remains the same, though. Overall,the script does what I want it to except for the exit code portion.)
Remove | echo $?. you are processing the return code of echo command(last command).
Need some shell scripting help, especially with my if-then-else logic. I want to combine both conditions, but not sure if the file checks will work the same? Should I be doing something like a nested if?? My script uses the if statements to do file checks to see if they exist, then do something..
There is probably a better way to do file checks part too.
Any help, critique would be appreciated. Thanks.
Here's my code, it sort of works.
if [ $# != 1 ]; then
echo "Usage: getlogs.sh <remote-host>" 2>&1
exit 1
fi
#Declare variables
STAMP=`date '+%Y%m%d-%H:%M'`
REMOTE_MYCNF=/var/log/mysoft/mysoft.log
REMOTE_GZ=/var/log/mysoft/mysoft.log.1.gz
REMOTE_DIR=/var/log/mysoft/
BACKUP_DIR=/home/mysql/dev/logs/
NEWLOG="foo-temp.log"
export REMOTE_MYCNF STAMP SHORTNAME
export REMOTE_DIR REMOTE_GZ
#Copy file over
echo "START..." 2>&1
test -f $BACKUP_DIR$1.mysoft.log
if [ $? = 0 ]; then
echo "Local log file exists, clean up for new copy..." 2>&1
/bin/rm $BACKUP_DIR$1.mysoft.log
exit 0
else
echo "File does not exist, getting a new copy..." 2>&1
fi
echo "Checking remotely in $1 for foo logfile $REMOTE_MYCNF $STAMP" 2>&1
if [ ! -f $REMOTE_MYCNF ]; then
echo "File exists remotely, creating new logfile and copy here...." 2>&1
ssh $1 "zcat $REMOTE_GZ >> $REMOTE_DIR$NEWLOG"
ssh $1 "cat $REMOTE_MYCNF >> $REMOTE_DIR$NEWLOG"
/usr/bin/scp $1:$REMOTE_DIR$NEWLOG $BACKUP_DIR$1.mysoft.log
echo "end remote copy" 2>&1
echo "Cleaning up remote files" 2>&1
ssh $1 "rm $REMOTE_DIR$NEWLOG"
exit 0
else
echo "Unable to get file" 2>&1
exit 0
fi
Updated code using help:
if [ -f $BACKUP_DIR$1.mysoft.log ]; then
echo "Local log file exists, clean up for new copy..." 2>&1
/bin/rm $BACKUP_DIR$1.mysoft.log
exit 0
else
echo "File does not exist, getting a new copy..." 2>&1
echo "Checking remotely in $1 for foo logfile $REMOTE_MYCNF $STAMP" 2>&1
if [ ! -f $REMOTE_MYCNF ]; then
echo "File exists remotely, creating new logfile and bring a copy here...." 2>&1
ssh $1 "zcat $REMOTE_GZ >> $REMOTE_DIR$NEWLOG"
ssh $1 "cat $REMOTE_MYCNF >> $REMOTE_DIR$NEWLOG"
/usr/bin/scp $1:$REMOTE_DIR$NEWLOG $BACKUP_DIR$1.mysoft.log
echo "end remote copy" 2>&1
echo "Cleaning up remote files" 2>&1
ssh $1 "rm $REMOTE_DIR$NEWLOG"
exit 0
else
echo "Unable to get file" 2>&1
exit 0
fi
fi
The file test can be combined into one statement like this:
if [ -f $BACKUP_DIR$1.mysoft.log ]; then
At a glance, it doesn't look like you need to export any of the variables.
If you intend for the if [ ! -f $REMOTE_MYCNF ]; then block to be executed within the else of the previous if, just move it within it.
if ...
then
foo
else
if ...
then
bar
else
baz
fi
fi
If you need to check two things:
if [ "$foo" = "bar" && "$baz" = "qux" ]
Always quote your variables.
In a short script it's fine to use positional parameters such as $1 directly, but it makes a longer script easier to understand if a variables with meaningful names are assigned their values near the top.
remote_host=$1
When you want to echo errors to stderr do it this way:
echo "Message" >&2
The way you have it, you're echoing the message and any errors the echo itself may produce (pretty rare) to stdout.