¿Cómo enumero todos los trabajos cron para todos los usuarios?

Resuelto yukondude asked hace 16 años • 25 respuestas

¿Existe algún comando o script existente que me permita ver todos los trabajos cron programados de un sistema *NIX a la vez? Me gustaría que incluyera todos los crontabs de usuario, así como /etc/crontaby todo lo que esté en /etc/cron.d. También sería bueno ver los comandos específicos ejecutados run-partsen /etc/crontab.

Idealmente, me gustaría que el resultado estuviera en forma de columna agradable y ordenado de alguna manera significativa.

Luego podría fusionar estos listados de varios servidores para ver el "programa de eventos" general.

Estaba a punto de escribir ese guión yo mismo, pero si alguien ya se ha tomado la molestia...

yukondude avatar Sep 26 '08 01:09 yukondude
Aceptado

Tendrías que ejecutar esto como root, pero:

for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l; done

recorrerá cada nombre de usuario enumerando su crontab. Los crontabs son propiedad de los respectivos usuarios, por lo que no podrá ver el crontab de otro usuario sin ser él o root.


Edite si desea saber a qué usuario pertenece un crontab, useecho $user

for user in $(cut -f1 -d: /etc/passwd); do echo $user; crontab -u $user -l; done
Kyle Burton avatar Sep 25 '2008 18:09 Kyle Burton

Terminé escribiendo un script (estoy tratando de aprender por mí mismo los puntos más finos de los scripts bash, por eso no ves algo como Perl aquí). No es exactamente un asunto simple, pero hace la mayor parte de lo que necesito. Utiliza la sugerencia de Kyle para buscar los crontabs de usuarios individuales, pero también se ocupa /etc/crontab(incluidos los scripts iniciados por run-partsin /etc/cron.hourly, /etc/cron.dailyetc.) y los trabajos en el /etc/cron.ddirectorio. Toma todos esos y los combina en una pantalla similar a 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 al usuario y, más o menos, ordena por hora y minuto para que pueda ver el horario diario.

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}"
yukondude avatar Sep 26 '2008 00:09 yukondude

En Ubuntu o Debian, puede ver crontab /var/spool/cron/crontabs/y luego encontrará un archivo para cada usuario. Por supuesto, eso es solo para crontab específicos del usuario.

Para Redhat 6/7 y Centos, el crontab se encuentra en /var/spool/cron/.

 avatar Dec 12 '2008 03:12