[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.
Still lots of problems...you're looping over all users when one was provided, you didn't close out one of your for loops, your method of grabbing the user name when one was not provided won't work, and your method of restoring from backup is still invalid. Please see my previous post, and please pay attention to the first section, where you ignore the script, shut it down, close it out, and focus SOLELY on the backup and restore commands (namely restore).
Remember, everything you can put in a script, you can also run by itself on the shell. That's all a script is, a collection of shell commands.
You also need to stick an echo in front of all of your crontab calls until you get this figured out. Running arbitrary commands with unknown arguments and invalid redirection as root is GOING to break something. I hope this is a disposable VM you're testing on.
Last edited by suicidaleggroll; 06-22-2016 at 11:00 AM.
#!/bin/bash
set -xv
bkuplocation="/systems/homes/cronjobs_bk/$hostname"
cron_source="/var/spool/cron/crontabs/*"
hostname=$(hostname -s)
#Help function
function show_help {
echo " Command line switches -m is required, -p & -u are optional."
echo " -m --Sets the value for option to backup or restore (backup/restore)."
echo " -p --(OPTIONAL) Sets the path to backup from and restore to."
echo " -u --(OPTIONAL) Sets the user jobs to backup."
echo " -h --Displays this help message. No further functions are performed."
exit 1
}
#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."
show_help
;;
esac
done
case $method in
backup)
if [ ! -d "$bkuplocation" ]; then
mkdir "$bkuplocation"
fi
if [[ -z "$location" && -z "$user" ]]; then
for i in "$cron_source"; do
echo "crontab -l -u $i > $bkuplocation/$i"
done
elif [[ ! -z "$location" && ! -z "$user" ]]; then
echo "crontab -l -u $user > $location/$user"
elif [[ -z "$location" && ! -z "$user" ]]; then
echo "crontab -l -u $user > $bkuplocation/$user"
elif [[ ! -z "$location" && -z "$user" ]]; then
for i in "$cron_source"; do
echo "crontab -l -u $i > $location/$i"
done
else
show_help
fi
;;
restore)
if [ ! -d "$bkuplocation" ]; then
echo "no backup found for $host"
fi
if [[ -z "$location" && -z "$user" ]]; then
for i in "$bkuplocation"; do
echo "crontab $i"
done
elif [[ ! -z "$location" && ! -z "$user" ]]; then
echo "crontab $user < $location/$user"
elif [[ ! -z "$location" && -z "$user" ]]; then
for i in "$location"; do
echo "crontab $i < $location"
done
elif [[ -z "$location" && ! -z "$user" ]]; then
echo "crontab $user < $bkuplocation/$user"
else
show_help
fi
;;
esac
shift $((OPTIND-1))
exit 0
however, i am getting the following output, to me it seems fine? any thoughts?
Code:
$ sudo ./getopts.sh -m backup
bkuplocation="/systems/homes/cronjobs_bk/$hostname"
+ bkuplocation=/systems/homes/cronjobs_bk/
cron_source="/var/spool/cron/crontabs/*"
+ cron_source='/var/spool/cron/crontabs/*'
hostname=$(hostname -s)
hostname -s
++ hostname -s
+ hostname=mysql11
#Help function
function show_help {
echo " Command line switches -m is required, -p & -u are optional."
echo " -m --Sets the value for option to backup or restore (backup/restore)."
echo " -p --(OPTIONAL) Sets the path to backup from and restore to."
echo " -u --(OPTIONAL) Sets the user jobs to backup."
echo " -h --Displays this help message. No further functions are performed."
exit 1
}
#Check the number of arguments. If none are passed, print help and exit.
numargs=$#
+ numargs=2
if [ $numargs -eq 0 ]; then
show_help
fi
+ '[' 2 -eq 0 ']'
# 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."
show_help
;;
esac
done
+ getopts 'm:p?u?h?' options
+ case $options in
+ method=
+ getopts 'm:p?u?h?' options
case $method in
backup)
if [ ! -d $bkuplocation ]; then
mkdir $bkuplocation
fi
if [[ -z $location && -z $user ]]; then
for i in $cron_source; do
crontab -l -u $i > "$bkuplocation/$i"
done
elif [[ ! -z $location && ! -z $user ]]; then
crontab -l -u $user > "$location/$user"
elif [[ -z $location && ! -z $user ]]; then
crontab -l -u $user > "$bkuplocation/$user"
elif [[ ! -z $location && -z $user ]]; then
for i in $cron_source; do
crontab -l -u $i > "$location/$i"
done
else
show_help
fi
;;
restore)
if [ ! -d $bkuplocation ]; then
echo "no backup found for $host"
fi
if [[ -z $location && -z $user ]]; then
for i in $bkuplocation; do
crontab $i
done
elif [[ ! -z $location && ! -z $user ]]; then
crontab $user < "$location/$user"
elif [[ ! -z $location && -z $user ]]; then
for i in $location; do
crontab $i < $location
done
elif [[ -z $location && ! -z $user ]]; then
crontab $user < "$bkuplocation/$user"
else
show_help
fi
;;
esac
+ case $method in
shift $((OPTIND-1))
+ shift 2
exit 0
+ exit 0
Last edited by linuxnewbie0101; 06-22-2016 at 12:40 PM.
You can get rid of half of your elif statements if you add one if before your "case $method in":
Code:
if [ -z $location ]; then
location=$bkuplocation
fi
Then just use $location from then on.
As for your problem, optarg needs to be capitalized:
method=$OPTARG
and so on
Your syntax for optstring is also incorrect, it should be:
Code:
while getopts m:p:u:h options; do
The very first step in debugging a program like this should be to print out all of the variables you think you're setting and verify they are what you think they are. "echo" is your friend, use it.
For example, you still aren't passing the user correctly to crontab when $user is not set...$i does not contain what you think it contains.
Comment out all of your calls to crontab and stick some echos in there to make sure you're going to call what you think you're going to call before actually doing it and potentially screwing something up. Passing the wrong argument to crontab can permanently wipe out a user's cron. Nobody develops scripts the way you're doing it here, entering seemingly random commands and arguments you don't understand without knowing variable contents or verifying any of it, then running it as root, where a small syntax error could cause MAJOR damage to the system. It's a recipe for disaster. As I said before, I sure hope this is a disposable VM you're testing on and not a live system, and that you've already made backups of ALL of the user crontabs in a safe location (that's not referenced anywhere in this script).
Last edited by suicidaleggroll; 06-22-2016 at 12:55 PM.
so this is the new updated script. however, when i debug the errors follows. thanks for all you guys help.
Code:
#!/bin/bash
set -xv
bkuplocation="/systems/homes/cronjobs_bk"
cron_source="/var/spool/cron/crontabs"
hostname=$(hostname -s)
#Help function
function show_help {
echo " Command line switches -m is required, -p & -u are optional."
echo " -m --Sets the value for option to backup or restore (backup/restore)."
echo " -p --(OPTIONAL) Sets the path to backup from and restore to."
echo " -u --(OPTIONAL) Sets the user jobs to backup."
echo " -h --Displays this help message. No further functions are performed."
exit 1
}
#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:puh options; do
case $options in
m)
method=$OPTARG
;;
p)
location=$OPTARG
;;
u)
user=$OPTARG
;;
h)
show_help
;;
\?) echo -e "Option $OPTARG not allowed."
show_help
;;
esac
#done
cd $cron_source
case $method in
backup)
if [[ ! -d "$bkuplocation" ]]; then
mkdir "$bkuplocation"
fi
if [[ -z "$location" && -z "$user" ]]; then
cd $cron_source
for i in *; do
"crontab -l -u $i > $bkuplocation/$i"
done
elif [[ ! -z "$location" && ! -z "$user" ]]; then
"crontab -l -u $user > $location/$user"
elif [[ -z "$location" && ! -z "$user" ]]; then
"crontab -l -u $user > $bkuplocation/$user"
elif [[ ! -z "$location" && -z "$user" ]]; then
for i in *; do
"crontab -l -u $i > $location/$i"
done
else
show_help
fi
;;
restore)
if [[ ! -d "$bkuplocation" ]]; then
echo "no backup found for $host"
fi
if [[ -z "$location" && -z "$user" ]]; then
for i in *; do
"crontab $i"
done
elif [[ ! -z "$location" && ! -z "$user" ]]; then
"crontab $user < $location/$user"
elif [[ ! -z "$location" && -z "$user" ]]; then
for i in *; do
"crontab $i < $location"
done
elif [[ -z "$location" && ! -z "$user" ]]; then
"crontab $user < $bkuplocation/$user"
else
show_help
fi
;;
esac
done
shift $((OPTIND-1))
exit 0
debug output:
Code:
~$ sudo ./getopts.sh -m backup
bkuplocation="/systems/homes/cronjobs_bk"
+ bkuplocation=/systems/homes/cronjobs_bk
cron_source="/var/spool/cron/crontabs"
+ cron_source=/var/spool/cron/crontabs
hostname=$(hostname -s)
hostname -s
++ hostname -s
+ hostname=mysql11
#Help function
function show_help {
echo " Command line switches -m is required, -p & -u are optional."
echo " -m --Sets the value for option to backup or restore (backup/restore)."
echo " -p --(OPTIONAL) Sets the path to backup from and restore to."
echo " -u --(OPTIONAL) Sets the user jobs to backup."
echo " -h --Displays this help message. No further functions are performed."
exit 1
}
#Check the number of arguments. If none are passed, print help and exit.
numargs=$#
+ numargs=2
if [ $numargs -eq 0 ]; then
show_help
fi
+ '[' 2 -eq 0 ']'
# 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."
show_help
;;
esac
#done
#if [ -z $location ]; then
# location=$bkuplocation
#fi
cd $cron_source
case $method in
backup)
if [ ! -d "$bkuplocation" ]; then
mkdir "$bkuplocation"
fi
if [[ -z "$location" && -z "$user" ]]; then
cd $cron_source
for i in *; do
"crontab -l -u $i > $bkuplocation/$i"
done
elif [[ ! -z "$location" && ! -z "$user" ]]; then
"crontab -l -u $user > $location/$user"
elif [[ -z "$location" && ! -z "$user" ]]; then
"crontab -l -u $user > $bkuplocation/$user"
elif [[ ! -z "$location" && -z "$user" ]]; then
for i in *; do
"crontab -l -u $i > $location/$i"
done
else
show_help
fi
;;
restore)
if [ ! -d "$bkuplocation" ]; then
echo "no backup found for $host"
fi
if [[ -z "$location" && -z "$user" ]]; then
for i in *; do
"crontab $i"
done
elif [[ ! -z "$location" && ! -z "$user" ]]; then
"crontab $user < $location/$user"
elif [[ ! -z "$location" && -z "$user" ]]; then
for i in *; do
"crontab $i < $location"
done
elif [[ -z "$location" && ! -z "$user" ]]; then
"crontab $user < $bkuplocation/$user"
else
show_help
fi
;;
esac
done
+ getopts :m:p:u:h options
+ case $options in
+ method=backup
+ cd /var/spool/cron/crontabs
+ case $method in
+ '[' '!' -d /systems/homes/cronjobs_bk ']'
+ [[ -z '' ]]
+ [[ -z '' ]]
+ cd /var/spool/cron/crontabs
+ for i in '*'
+ 'crontab -l -u mysql > /systems/homes/cronjobs_bk/mysql'
./getopts.sh: line 59: crontab -l -u mysql > /systems/homes/cronjobs_bk/mysql: No such file or directory
+ for i in '*'
+ 'crontab -l -u root > /systems/homes/cronjobs_bk/root'
./getopts.sh: line 59: crontab -l -u root > /systems/homes/cronjobs_bk/root: No such file or directory
+ getopts :m:p:u:h options
shift $((OPTIND-1))
+ shift 2
exit 0
+ exit 0
now if i ran these manually, it works. ?????scratch my head?????
Code:
+ 'crontab -l -u mysql > /systems/homes/cronjobs_bk/mysql'
./getopts.sh: line 59: crontab -l -u mysql > /systems/homes/cronjobs_bk/mysql: No such file or directory
+ for i in '*'
+ 'crontab -l -u root > /systems/homes/cronjobs_bk/root'
./getopts.sh: line 59: crontab -l -u root > /systems/homes/cronjobs_bk/root: No such file or directory
Last edited by linuxnewbie0101; 06-22-2016 at 03:45 PM.
For my part, with serious scripts I like to make functions, like your show_help function.
That helps to narrow debugging, I mean to know what part doesn't work
In this script, I would have done:
function getScriptOptions()
function setBackupDir()
function backup()
function restore()
For my part, with serious scripts I like to make functions, like your show_help function.
That helps to narrow debugging, I mean to know what part doesn't work
In this script, I would have done:
function getScriptOptions()
function setBackupDir()
function backup()
function restore()
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.