¿Existe un comando o un script que me permita ver todos los trabajos cron programados de un sistema *NIX a la vez? Me gustaría que incluyera todos los crontabs del usuario, así como /etc/crontab
, y todo lo que haya en /etc/cron.d
. También estaría bien ver los comandos específicos ejecutados por run-parts
en /etc/crontab
.
Idealmente, me gustaría la salida en una forma de columna agradable y ordenada de alguna manera significativa.
Entonces podría fusionar estos listados de múltiples servidores para ver el global "calendario de eventos."";
Estaba a punto de escribir un script de este tipo yo mismo, pero si alguien ya se ha tomado la molestia...
Tendrías que ejecutar esto como root, pero:
for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l; done
hará un bucle sobre cada nombre de usuario listando su crontab. Los crontabs son propiedad de los respectivos usuarios, por lo que no podrás ver el crontab de otro usuario sin ser él o root.
Editar
si quieres saber a qué usuario pertenece un crontab, utiliza echo $usuario
.
for user in $(cut -f1 -d: /etc/passwd); do echo $user; crontab -u $user -l; done
Terminé escribiendo un script (estoy tratando de enseñarme a mí mismo los puntos más finos de las secuencias de comandos bash, así que por eso no ves algo como Perl aquí). No es exactamente un asunto sencillo, pero hace la mayor parte de lo que necesito. Utiliza la sugerencia de Kyle para buscar crontabs de usuarios individuales, pero también se ocupa de /etc/crontab
(incluyendo los scripts lanzados por run-parts
en /etc/cron.hourly
, /etc/cron.daily
, etc.) y los trabajos en el directorio /etc/cron.d
. Toma todo esto y lo combina en una pantalla como la siguiente:
mi h d m w user command
09,39 * * * * root [ -d /var/lib/php5 ] && find /var/lib/php5/ -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 | xargs -r -0 rm
47 */8 * * * root rsync -axE --delete --ignore-errors / /mirror/ >/dev/null
17 1 * * * root /etc/cron.daily/apt
17 1 * * * root /etc/cron.daily/aptitude
17 1 * * * root /etc/cron.daily/find
17 1 * * * root /etc/cron.daily/logrotate
17 1 * * * root /etc/cron.daily/man-db
17 1 * * * root /etc/cron.daily/ntp
17 1 * * * root /etc/cron.daily/standard
17 1 * * * root /etc/cron.daily/sysklogd
27 2 * * 7 root /etc/cron.weekly/man-db
27 2 * * 7 root /etc/cron.weekly/sysklogd
13 3 * * * archiver /usr/local/bin/offsite-backup 2>&1
32 3 1 * * root /etc/cron.monthly/standard
36 4 * * * yukon /home/yukon/bin/do-daily-stuff
5 5 * * * archiver /usr/local/bin/update-logs >/dev/null
Tenga en cuenta que muestra el usuario, y más o menos ordena por hora y minuto para que pueda ver la programación diaria.
Hasta ahora, lo he probado en Ubuntu, Debian y Red Hat AS.
#!/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)
# 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}"
Depende de su versión de cron. Usando Vixie cron en FreeBSD, puedo hacer algo como esto:
(cd /var/cron/tabs && grep -vH ^# *)
si lo quiero más delimitado por las pestañas, podría hacer algo como esto
(cd /var/cron/tabs && grep -vH ^# * | sed "s/:/ /")
Donde eso es un tabulador literal en la parte de reemplazo de sed.
Puede ser más independiente del sistema hacer un bucle a través de los usuarios en /etc/passwd
y hacer crontab -l -u $user
para cada uno de ellos.