-
-
Save adamamyl/92cc98b64d41d93c2c86 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# Provides missing crontab editing | |
# Note: Synology crond requires arguments separated by a TAB character | |
# and the crontab user field only supports root. These requirements are | |
# enforced by this script. | |
# | |
# John Kelly, 2013-05-03 | |
# Richard Cook, 2014-02-21 | |
# | |
SCRIPTPATH=$(readlink -f $0) | |
SCRIPTNAME=$(basename "$SCRIPTPATH") | |
# Default path to crontab file | |
CRONTABPATH=/etc/crontab | |
# Failed edits are kept in this file | |
CHKCRON=/etc/crontab.chk | |
# Previous version | |
TMPNAME=/etc/crontab.old | |
# Max versions to keep. One or greater | |
MAXVER=10 | |
# Set to your editor of choice | |
EDITOR=${EDITOR} | |
usage() { | |
echo -e "Usage: $SCRIPTNAME [-l | -v | -f | -e | -h]\n" | |
} | |
# Check for selected editor. Default to vi | |
EDITOR=$(/usr/bin/which $EDITOR 2>&1) | |
[[ ! -x "$EDITOR" ]] && EDITOR=/bin/vi | |
show_help() { | |
echo -e 'Provides basic access to the crontab file' | |
echo -e 'with simple format checks\n' | |
usage | |
echo ' -l : Lists the current contents of the root crontab file' | |
echo ' -v : Verifies the current contents of the root crontab file' | |
echo ' -f : Refreshes the cron daemon' | |
echo ' -e : Edits the crontab file and refreshes the cron daemon if' | |
echo ' the file is actually changed; otherwise does nothing' | |
echo -e ' -h : Shows this help text\n' | |
} | |
verify_crontab() { | |
# Synocron is very picky. Check the file format | |
( # Start of output redirection block | |
IFS=" | |
" | |
cat $1 | \ | |
while read LINE; do | |
# Find out if empty or the first character is a # | |
echo "$LINE" | awk '{print $1}' | egrep "^#|^$" > /dev/null 2>&1 | |
if [[ $? = 0 ]]; then | |
# Copy over comment/blank lines exactly | |
echo "$LINE" | |
else | |
unset IFS | |
# test convert using tabs to compare results | |
echo "$LINE" | while read MIN HO MD MO WD WH COM; do | |
echo -e "$MIN\t$HO\t$MD\t$MO\t$WD\troot\t$COM" | |
done | |
IFS=" | |
" | |
fi | |
done | |
) > $2 # end of output redirection block | |
# Compare files and return the result | |
diff $1 $2 > /dev/null 2>&1 | |
return $? | |
} | |
restart_cron() { | |
echo 'Refreshing cron daemon.' | |
SYNOSERVICE=/usr/syno/sbin/synoservicectl | |
if [ -f $SYNOSERVICE ]; then | |
$SYNOSERVICE --restart crond | |
return | |
fi | |
CRONDRC=/usr/syno/etc/rc.d/S04crond.sh | |
if [ -f $CRONDRC ]; then | |
$CRONDRC stop | |
$CRONDRC start | |
return | |
fi | |
echo 'Don'"'"'t know how to restart cron service.' | |
exit 1 | |
} | |
archive_crontabs() { # Keep up to MAXVER versions | |
ARCVER=$MAXVER | |
while [[ $ARCVER -gt 1 ]]; do | |
PRVVER=$(expr $ARCVER - 1) | |
if [ -f $TMPNAME.$PRVVER ]; then | |
mv -f $TMPNAME.$PRVVER $TMPNAME.$ARCVER | |
fi | |
ARCVER=$PRVVER | |
done | |
cp $TMPNAME $TMPNAME.1 | |
} | |
edit_crontab() { | |
archive_crontabs | |
cp $1 $TMPNAME | |
$EDITOR $1 | |
diff $1 $TMPNAME > /dev/null 2>&1 | |
if [[ $? = 0 ]]; then | |
echo "No changes made. Doing nothing." | |
else | |
if verify_crontab $1 $2; then | |
echo 'Crontab altered.' | |
echo "Previous version saved in $TMPNAME" | |
rm -f $2 | |
restart_cron | |
else | |
echo 'Crontab file is NOT in the correct Synology format.' | |
echo 'Please use TABs between fields and specify root in sixth field.' | |
echo "Your version is saved in $2. Restoring original version." | |
diff $1 $2 | cat -A | |
cat $1 > $2 | |
cat $TMPNAME > $1 | |
fi | |
fi | |
exit 0 | |
} | |
check_command() { | |
if [[ "$COMMAND" != '' ]]; then | |
echo -e 'You must specify exactly one command.\n' | |
usage | |
exit 1 | |
fi | |
} | |
COMMAND= | |
while getopts p:lvfeh FLAG; do | |
case $FLAG in | |
p) CRONTABPATH=$(readlink -f $OPTARG);; | |
l) check_command; COMMAND=l;; | |
v) check_command; COMMAND=v;; | |
f) check_command; COMMAND=f;; | |
e) check_command; COMMAND=e;; | |
h) check_command; COMMAND=h;; | |
esac | |
done | |
if [[ "$COMMAND" = '' ]]; then | |
usage | |
exit 1 | |
fi | |
case $COMMAND in | |
l) | |
echo "crontab at $CRONTABPATH" | |
cat $CRONTABPATH;; | |
v) | |
TEMPPATH=$(mktemp) | |
if verify_crontab $CRONTABPATH $TEMPPATH; then | |
echo "crontab at $CRONTABPATH is valid" | |
else | |
echo "crontab at $CRONTABPATH is not valid:" | |
diff $CRONTABPATH $TEMPPATH | cat -A | |
fi | |
rm $TEMPPATH;; | |
f) restart_cron;; | |
e) edit_crontab $CRONTABPATH $CHKCRON;; | |
h) show_help;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment