-
-
Save Zitrax/3819487 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# System-wide crontab file and cron job directory. Change these for your system. | |
CRONTAB='/etc/crontab' | |
CRONDIR='/etc/cron.d' | |
# Single tab character. Annoyingly necessary. | |
tab=$(echo -en "\t") | |
# Given a stream of crontab lines, exclude non-cron job lines, replace | |
# whitespace characters with a single space, and remove any spaces from the | |
# beginning of each line. | |
function clean_cron_lines() { | |
while read line ; do | |
echo "${line}" | | |
egrep --invert-match '^($|\s*#|\s*[[:alnum:]_]+=)' | | |
sed --regexp-extended "s/\s+/ /g" | | |
sed --regexp-extended "s/^ //" | |
done; | |
} | |
# Given a stream of cleaned crontab lines, echo any that don't include the | |
# run-parts command, and for those that do, show each job file in the run-parts | |
# directory as if it were scheduled explicitly. | |
function lookup_run_parts() { | |
while read line ; do | |
match=$(echo "${line}" | egrep -o 'run-parts (-{1,2}\S+ )*\S+') | |
if [[ -z "${match}" ]] ; then | |
echo "${line}" | |
else | |
cron_fields=$(echo "${line}" | cut -f1-6 -d' ') | |
cron_job_dir=$(echo "${match}" | awk '{print $NF}') | |
if [[ -d "${cron_job_dir}" ]] ; then | |
for cron_job_file in "${cron_job_dir}"/* ; do # */ <not a comment> | |
[[ -f "${cron_job_file}" ]] && echo "${cron_fields} ${cron_job_file}" | |
done | |
fi | |
fi | |
done; | |
} | |
# Temporary file for crontab lines. | |
temp=$(mktemp) || exit 1 | |
# Add all of the jobs from the system-wide crontab file. | |
cat "${CRONTAB}" | clean_cron_lines | lookup_run_parts >"${temp}" | |
# Add all of the jobs from the system-wide cron directory. | |
cat "${CRONDIR}"/* | clean_cron_lines >>"${temp}" # */ <not a comment> | |
# Add each user's crontab (if it exists). Insert the user's name between the | |
# five time fields and the command. | |
while read user ; do | |
crontab -l -u "${user}" 2>/dev/null | | |
clean_cron_lines | | |
sed --regexp-extended "s/^((\S+ +){5})(.+)$/\1${user} \3/" >>"${temp}" | |
done < <((cut --fields=1 --delimiter=: /etc/passwd && find /home/ -maxdepth 1 -mindepth 1 -type d -printf "%f\n") | sort | uniq) | |
# Output the collected crontab lines. Replace the single spaces between the | |
# fields with tab characters, sort the lines by hour and minute, insert the | |
# header line, and format the results as a table. | |
cat "${temp}" | | |
sed --regexp-extended "s/^(\S+) +(\S+) +(\S+) +(\S+) +(\S+) +(\S+) +(.*)$/\1\t\2\t\3\t\4\t\5\t\6\t\7/" | | |
sort --numeric-sort --field-separator="${tab}" --key=2,1 | | |
sed "1i\mi\th\td\tm\tw\tuser\tcommand" | | |
column -s"${tab}" -t | |
rm --force "${temp}" |
Try to add this code for weekly, monthly, etc. scripts, before "Output the collected crontab lines".
The run time assigned for each job is an aproximation extracted from https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s2-autotasks-cron-configuring.html ... and can vary from one system to another.
# Hourly, Daily, Weekly and Monthly scripts
CRONDIR_HOURLY='/etc/cron.hourly'
CRONDIR_DAILY='/etc/cron.daily'
CRONDIR_WEEKLY='/etc/cron.weekly'
CRONDIR_MONTHLY='/etc/cron.monthly'
ls -lR "${CRONDIR_HOURLY}" | grep "^-" | awk -v dir="${CRONDIR_HOURLY}" {'print "01 * * * * root "dir"/" $9'} >>"${temp}"
ls -lR "${CRONDIR_DAILY}" | grep "^-" | awk -v dir="${CRONDIR_DAILY}" {'print "02 4 * * * root "dir"/" $9'} >>"${temp}"
ls -lR "${CRONDIR_WEEKLY}" | grep "^-" | awk -v dir="${CRONDIR_WEEKLY}" {'print "22 4 * * 0 root "dir"/" $9'} >>"${temp}"
ls -lR "${CRONDIR_MONTHLY}" | grep "^-" | awk -v dir="${CRONDIR_MONTHLY}" {'print "42 4 1 * * root "dir"/" $9'} >>"${temp}"
We should expand this to include
/etc/anacrontab
in addition to the default/etc/crontab
What I did was this:
`CRONTAB='/etc/crontab /etc/anacrontab'
and then I removed the quotes and routed any errors to null (to hide missing files)
cat ${CRONTAB} 2>/dev/null | clean_cron_lines | lookup_run_parts >"${temp}"
actually this may not be enough, I still do not see results for weekly or monthly
You should modify lookup_run_parts
to correctly parse anacron entries. From my fork:
# sames as lookup_run_parts, but 5 fields, not 6
function lookup_anacron_parts() {
while read line ; do
match=$(echo "${line}" | egrep -o 'run-parts (-{1,2}\S+ )*\S+')
if [[ -z "${match}" ]] ; then
echo "${line}"
else
cron_fields=$(echo "${line}" | cut -f1-5 -d' ')
cron_job_dir=$(echo "${match}" | awk '{print $NF}')
if [[ -d "${cron_job_dir}" ]] ; then
for cron_job_file in "${cron_job_dir}"/* ; do # */ <not a comment>
[[ -f "${cron_job_file}" ]] && echo "${cron_fields} ${cron_job_file}"
done
fi
fi
done;
}
We should expand this to include
/etc/anacrontab
in addition to the default/etc/crontab
What I did was this:
`CRONTAB='/etc/crontab /etc/anacrontab'
and then I removed the quotes and routed any errors to null (to hide missing files)
cat ${CRONTAB} 2>/dev/null | clean_cron_lines | lookup_run_parts >"${temp}"
actually this may not be enough, I still do not see results for weekly or monthly
apparently my default /etc/anacrontab in centos contains different columns which will need more code to handle
period in days delay in minutes job-identifier command
there are also many other files this script fails to handle
ls /etc/cron.*
is far more then justcron.d