[SOLVED] using getopts with flags to backup cronjobs
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
In addition, $location will never be blank. It will either be set to bkuplocation or defined as a argument. In fact you only need one such variable just like your $method variable.
Code:
#parameter expansion for $host-$user
file="$hostname-$user"
userfile=${file##*-}
for users in "$host-*"; do
crontab $user < $bkuplocation/$userfile
done
Have you tested this code yet? This statement "userfile=${file##*-}" will strip the user from the string $host-$user but as written $hostname and possibly $user has never been defined. Your $user variable will be $host-$user for all matches in the directory. I would probably use something else in the restore section so you do not get confused with the user entered $user variable.
You need to extract the username in the loop. As suggest by others I would use echo to verify the commands were correct while you were debugging your code. And note at the moment it isn't
yes i have tested the code, everything works as expected, excepted for the new error handling block.
the parameter expansion is intent to strip the filename when it restores. when backup occur it adds $host in front of the user. but when calling restore with -u user, the file on $bkuplocation will be $host-$user so i wanted to remove $host when restore.
can you give me a hint on what im doing wrong here.
Code:
if [[ $method='backup' && $location=$bkuploacation ]]; then
if [[ ! -z $user && $user != ls $cron_source | grep $user ]]; then
echo " ERROR: no cronjob found for $host $user."
exit 1
fi
fi
can i set something like
Code:
test="ls $cron_source | grep $user"
if [[ $method='backup' && $location=$bkuploacation ]]; then
if [[ ! -z $user && $user != $test ]]; then
echo " ERROR: no cronjob found for $host $user."
exit 1
fi
fi
TY
update:
maybe
Code:
if [[ $method='backup' && ! -z $user ]]; then
if [[ $user != "`ls $cron_source | grep $user`" ]]; then
echo " ERROR: no cronjob found for $host $user."
exit 1
fi
fi
Last edited by linuxnewbie0101; 06-24-2016 at 01:11 PM.
I know what you are trying to accomplish. I have not tested your code and it seems you do not always post the latest version so I can only go by what I see.
I do not see why the value of $location or $bkuplocation matters for determining a valid user. Yes, what you posted using the $test case will work.
#!/bin/bash -e
bkuplocation="/systems/homes/cronjobs_bk"
cron_source="/var/spool/cron/crontabs"
host=$(hostname -s)
location=$bkuplocation
method='backup'
#comment the above 2 lines if -m is a require at later time
#Help function
function show_help {
echo " Command line switches are -m , -p & -u"
echo " -m --Sets the value for option to backup or restore (backup/restore). Default to backup"
echo " -p --Sets the path to backup from and restore to. Default to $bkuplocation"
echo " -u --Sets the user jobs to backup. Default to all"
echo " -h --Displays this help message. No further functions are performed."
exit 1
}
#Uncomment this block to ensure required arguments
#=======================================================================
#Check the number of arguments. If none are passed, print help and exit.
#numargs=$#
#if [ $numargs -eq 0 ]; then
# show_help
#fi
#=======================================================================
# Start getopts code
while getopts :m:p:u:h options; do
case $options in
m)
method=$OPTARG
;;
p)
location=$OPTARG
;;
u)
user=$OPTARG
;;
h)
show_help
;;
\?) echo -e "Option $OPTARG not allowed."/n
show_help
;;
esac
done
#Error checking for $bkuplocation and $location
if [[ ! -d $bkuplocation ]]; then
echo " ERROR: default backup location does not exist. Please make sure $bkuplocation is available or use -p to specify backup location."
exit 1
fi
if [[ ! -z $location && ! -d $location ]]; then
echo " ERROR: Specified location does not exist. Please provide another location or use default location."
exit 1
fi
#Error checking for user backup
if [[ $method='backup' && ! -z $user ]]; then
if [[ $user != $(ls $cron_source | grep $user) ]]; then
echo " ERROR: no cronjob found for $host $user."
exit 1
fi
fi
#Error checking for user restore
if [[ $method='restore' && -z $location ]]; then
if [ ! -z $user && $host-$user != $(ls $bkuplocation | grep $host-$user) ]; then
echo " ERROR: no cron backup found for $host $user."
exit 1
fi
fi
if [[ $method='restore' && ! -z $location ]]; then
if [ ! -z $user && $user != $(ls $location | grep $user) ]; then
echo " ERROR: no backup crontab jobs found for $host $user."
exit 1
fi
fi
#parameter expansion for $host-$user
file="$hostname-$user"
userfile=${file##*-}
case $method in
backup)
if [[ -z $location && -z $user ]]; then
cd $cron_source
for users in *; do
crontab -l -u $users > $bkuplocation/$host-$users
done
elif [[ ! -z $location && ! -z $user ]]; then
crontab -l -u $user > $location/$host-$user
elif [[ -z $location && ! -z $user ]]; then
crontab -l -u $user > $bkuplocation/$host-$user
elif [[ ! -z $location && -z $user ]]; then
cd $cron_source
for users in *; do
crontab -l -u $users > $location/$host-$users
done
else
show_help
fi
;;
restore)
if [[ -z $location && -z $user ]]; then
cd $bkuplocation
for users in "$host-*"; do
crontab $users < $bkuplocation/$userfile
done
elif [[ ! -z $location && ! -z $user ]]; then
crontab $user < $location
elif [[ ! -z $location && -z $user ]]; then
cd $location
for users in *; do
crontab $users < $location
done
elif [[ -z $location && ! -z $user ]]; then
crontab $user < $bkuplocation/$host-$user
else
show_help
fi
;;
esac
exit 0
ok im hitting a wall again, this time its a strange one.
here are my latest code which works perfectly w/o error checking block.
this is the error message when i tried to run backup on root
ERROR: no backup crontab jobs found for mysql11 root.
it is triggering a error check for restore.
but im not running restore.
Code:
#!/bin/bash -ex
bkuplocation="/systems/homes/cronjobs_bk"
cron_source="/var/spool/cron/crontabs"
host=$(hostname -s)
location=$bkuplocation
method='backup'
#comment the above 2 lines if -m is a require at later time
#Help function
function show_help {
echo " Command line switches are -m , -p & -u"
echo " -m --Sets the value for option to backup or restore (backup/restore). Default to backup"
echo " -p --Sets the path to backup from and restore to. Default to $bkuplocation"
echo " -u --Sets the user jobs to backup. Default to all"
echo " -h --Displays this help message. No further functions are performed."
exit 1
}
#Uncomment this block to ensure required arguments
#=======================================================================
#Check the number of arguments. If none are passed, print help and exit.
#numargs=$#
#if [ $numargs -eq 0 ]; then
# show_help
#fi
#=======================================================================
# Start getopts code
while getopts :m:p:u:h options; do
case $options in
m)
method=$OPTARG
;;
p)
location=$OPTARG
;;
u)
user=$OPTARG
;;
h)
show_help
;;
\?) echo -e "Option $OPTARG not allowed."/n
show_help
;;
esac
done
#Error checking for $bkuplocation and $location
if [[ ! -d $bkuplocation ]]; then
echo " ERROR: default backup location does not exist. Please make sure $bkuplocation is available or use -p to specify backup location."
exit 1
fi
if [[ ! -z $location && ! -d $location ]]; then
echo " ERROR: Specified location does not exist. Please provide another location or use default location."
exit 1
fi
#Error checking for user backup
if [[ $method='backup' && ! -z $user ]]; then
if [[ ! -f "$cron_source/$user" ]]; then
echo " ERROR: no cronjob found for $host $user."
exit 1
fi
fi
#Error checking for user restore
if [[ $method='restore' && -z $location ]]; then
if [[ ! -z $user && ! -f "$bkuplocation/$host-$user" ]]; then
echo " ERROR: no cron backup found for $host $user."
exit 1
fi
fi
if [[ $method='restore' && ! -z $location ]]; then
if [[ ! -z $user && ! -f "$location/$user" ]]; then
echo " ERROR: no backup crontab jobs found for $host $user."
exit 1
fi
fi
#parameter expansion for $host-$user
file="$hostname-$user"
userfile=${file##*-}
case $method in
backup)
if [[ -z $location && -z $user ]]; then
cd $cron_source
for users in *; do
crontab -l -u $users > $bkuplocation/$host-$users
done
elif [[ ! -z $location && ! -z $user ]]; then
crontab -l -u $user > $location/$host-$user
elif [[ -z $location && ! -z $user ]]; then
crontab -l -u $user > $bkuplocation/$host-$user
elif [[ ! -z $location && -z $user ]]; then
cd $cron_source
for users in *; do
crontab -l -u $users > $location/$host-$users
done
else
show_help
fi
;;
restore)
if [[ -z $location && -z $user ]]; then
cd $bkuplocation
for users in "$host-*"; do
crontab $users < $bkuplocation/$userfile
done
elif [[ ! -z $location && ! -z $user ]]; then
crontab $user < $location
elif [[ ! -z $location && -z $user ]]; then
cd $location
for users in *; do
crontab $users < $location
done
elif [[ -z $location && ! -z $user ]]; then
crontab $user < $bkuplocation/$host-$user
else
show_help
fi
;;
esac
exit 0
Syntax error. The equals sign needs to be separated by a space.
if [[ $method = 'restore' ... ]]
Code:
for users in "$host-*"; do
crontab $users < $bkuplocation/$userfile
done
All you need to install jobs by file is crontab <file>. In your code to restore all, the loop will install all found files to the user that runs the script. Which if run by root will overwrite its jobs unintentionally. "< $bkuplocation/$userfile" is not required and in addition as I tried to explain earlier $userfile will be undefined.
$bkuplocation and $location are redundant, make your life simpler by using just one variable for the backup directory.
Variable = value can vary, eg can store default location or custom location
If you want to test existence of custom location, better do it at the option setting
Code:
while getopts :m:p:u:h options; do
case $options in
...
p)
bkuplocation=$OPTARG
if [[ ! -d $bkuplocation ]]; then
echo " ERROR: Specified location does not exist."
exit 1;
fi
;;
i am still having problem when restore and the part im stuck is the for loop to restore
Code:
restore)
if [[ -z $user ]]; then #restore for all users from default backup location
cd $bkuplocation
for users in "$host-*"; do
crontab $users < $bkuplocation/$host-$users
done
elif [[ ! -z $user ]]; then #restore with user input -p and -u
crontab $user < $bkuplocation/$host-$user
else
show_help #show Help function if not recognized
fi
;;
not sure how i can loop the files from $host-$user to $user......
Check out the man page for crontab. The syntax to restore a user's crontab is "crontab file". Similar to your backup loop you need to specify the user name in the restore loop.
keefax provided the code to extract the user name from the backup file $host-$user which needs to be inside the loop and has been modified a bit to fit your code.
Code:
for users in "$host-*"; do
username=${users##*-}
crontab -u $username $users
done
Untested but should be enough to get you going and to help you figure out the rest.
here are my latest code. stuck on restoring all users or individual users. not sure where im doing wrong, the outputs are showing what i want it to do.
please provide any feedbacks or errors that just pops up for you. been looking at this for days now and everything seems the same to me now. =(
TY
Code:
#!/bin/bash -ex
# This script by default is designed to backup all users crontab on host
# and must be run as root user.
# Use optional flags to set values other than default.
# default usage: script.sh
# optional usage: script.sh -m (backup||restore) -p (desire path) -u (user)
# see Help function for more detail on setting optionals.
bkuplocation="/systems/homes/cronjobs_bk" #default backup location
cron_source="/var/spool/cron/crontabs" #default crontab location
host=$(hostname -f) #host FQDN
logfile=$bkuplocation/logs/crontabs.log
timestamp=`date "+%Y.%m.%d %H:%M:%S"`
#location=$bkuplocation #defaults to backup location if no user input for -p
method='backup' #setting default method to backup
#comment the above 2 lines if -m is a require at later time
# Make sure only root can run this script
if [ "$(id -u)" != "0" ]; then # must run script as root
show_help
exit 1
fi
#checking for $bkuplocation.
if [[ ! -d $bkuplocation ]]; then
umask 007 #setting umask to root RW only
mkdir $bkuplocation
chgrp -R opsdr $bkuplocation #create $bkuplocation if it does not exist.
fi
#checking for $logfile location.
if [[ ! -d $bkuplocation/logs ]]; then
mkdir $bkuplocation/logs #create $bkuplocation if it does not exist.
chgrp -R opsdr $bkuplocation/logs
touch $logfile
fi
#echo -e $timestamp >> $logfile
#exec >> $logfile 2>&1 && tail $logfile
#Help function
function show_help {
echo " script must be run as root. "
echo " default usage : scriptname.sh -m (backup||restore) -p (location) -u (user) "
echo " Command line switches are -m , -p & -u "
echo " -m --Sets the value for option to backup or restore. Defaults to backup. "
echo " -p --Sets the path to backup from and restore to. Defaults to $bkuplocation "
echo " -u --Sets the user's job for backup. Defaults to all "
echo " -h --Displays this help message. No further functions are performed. "
exit 1
}
#Uncomment this block to ensure required arguments
#=======================================================================
#Check the number of arguments. If none are passed, print help and exit.
#numargs=$#
#if [ $numargs -eq 0 ]; then
# show_help
#fi
#=======================================================================
# Start getopts code
while getopts :m:p:u:h options; do
case $options in
m)
method=$OPTARG
;;
p)
bkuplocation=$OPTARG
;;
u)
user=$OPTARG
;;
h)
show_help
;;
\?) echo -e "Option $OPTARG not allowed."/n
show_help
;;
esac
done
#Error checking for user input $location
#if [[ $location != $bkuplocation && ! -d $location ]]; then
# echo " ERROR: Specified location $location does not exist. Please verify location or use default location by removing -p argument. "
# exit 1
#fi
if [[ ! -d $bkuplocation ]]; then
echo " ERROR: Specified location $location does not exist. Please verify location or use default location by removing -p argument. "
exit 1
fi
#Error checking for user input user backup
if [[ $method = 'backup' && ! -z $user ]]; then
if [[ ! -f "$cron_source/$user" ]]; then
echo " ERROR: no cronjob found for $user on $host."
exit 1
fi
fi
#Error checking for user restore
#if [[ $user != $(ls $cron_source | grep $user) ]]; then #verify user have jobs on $host before restore.
# echo " ERROR: $user currently do not have any jobs on $host ."
# exit 1
#fi
#Error checking for user restore
#if [[ $method = 'restore' ]]; then
# if [[ ! -z $user && ! -f "$bkuplocation/$host-$user" ]]; then
# echo " ERROR: no cron backup found for $user on $host ."
# exit 1
# fi
#fi
#if [[ $method = 'restore' && -d $bkuplocation ]]; then
# if [[ ! -z $user && ! -f "$bkuplocation/$user" ]]; then
# echo " ERROR: no backup crontab jobs found for $host $user."
# exit 1
# fi
#fi
#parameter expansion for $host-$user
#file="$host-$user"
#userfile=${file##*-}
case $method in
backup)
if [[ -z $user ]]; then #default backup, no user input
cd $cron_source
for users in *; do
crontab -l -u $users > $bkuplocation/$host-$users
done
elif [[ ! -z $user ]]; then #backup with user input -p and -u
crontab -l -u $user > $bkuplocation/$host-$user
else
show_help #show Help function if not recognized
fi
;;
restore)
if [[ -z $user ]]; then #restore for all users from default backup location
cd $bkuplocation
for users in "$host-*"; do
username=${users##*-}
crontab $username $user
done
elif [[ ! -z $user ]]; then #restore with user input -p and -u
crontab $user < $bkuplocation/$host-$user
else
show_help #show Help function if not recognized
fi
;;
esac
exit 0
Why use case for just 2 conditional statments at the end, using if else is enough, it's a matter of style though
You have to remove the quotes in for loop near line 145, correct a small typo ($user instead of $users) and correct command to restore a crontab should be ' crontab -u username file ' as michaelk suggested
So:
Code:
restore)
if [[ -z $user ]]; then #restore for all users from default backup location
cd $bkuplocation
for users in $host-*; do
username=${users##*-}
crontab -u $username $users
done
elif
...
Maybe choose a better variable name for $users here, like $userFile
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.