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


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

Idealmente, me gustaría que el resultado fuera una buena forma de columna y ordenada de una manera significativa.

Podría fusionar estos listados de varios servidores para ver el "calendario de eventos" general.

Estaba a punto de escribir un guión así, pero si alguien ya se ha tomado la molestia ...


730
2017-09-25 18:01


origen


Respuestas:


Tendría 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ás ver el crontab de otro usuario sin ellos ni como root.


Editar si quieres saber a qué usuario pertenece un crontab, utiliza echo $user

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

976
2017-09-25 18:07



Terminé escribiendo un guión (estoy tratando de enseñarme los puntos más finos de las secuencias de comandos bash, así que es por eso que no se ve 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 crontabs de usuarios individuales, pero también trata de /etc/crontab (incluidos los scripts lanzados por run-parts en /etc/cron.hourly, /etc/cron.daily, etc.) y los trabajos en el /etc/cron.d directorio. 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 ordena más o menos por hora y minuto para que pueda ver el programa 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}"

282
2017-09-26 00:50



En Ubuntu o Debian, puede ver crontab por /var/spool/cron/crontabs/ y luego hay un archivo para cada usuario allí. Eso es solo para crontab's específicos del usuario, por supuesto.


155
2017-12-12 03:56



Esto mostrará todas las entradas de crontab de todos los usuarios.

sed 's/^\([^:]*\):.*$/crontab -u \1 -l 2>\&1/' /etc/passwd | grep -v "no crontab for" | sh

28
2017-08-07 08:56



Depende de tu versión de Linux pero yo uso:

tail -n 1000 /var/spool/cron/*

como root Muy simple y muy corto.

Me da salida como:

==> /var/spool/cron/root <==
15 2 * * * /bla

==> /var/spool/cron/my_user <==
*/10 1 * * * /path/to/script

25
2017-08-03 00:40



Un pequeño refinamiento de la respuesta de Kyle Burton con un formato de salida mejorado:

#!/bin/bash
for user in $(cut -f1 -d: /etc/passwd)
do echo $user && crontab -u $user -l
echo " "
done

14
2017-07-06 11:29



getent passwd | cut -d: -f1 | perl -e'while(<>){chomp;$l = `crontab -u $_ -l 2>/dev/null`;print "$_\n$l\n" if $l}'

Esto evita jugar con passwd directamente, salta a los usuarios que no tienen entradas de cron y para aquellos que los tienen imprime el nombre de usuario y su crontab.

Mayormente dejando caer esto aquí para que pueda encontrarlo más tarde en caso de que alguna vez necesite buscarlo de nuevo.


13
2018-05-19 00:54



Si comprueba un clúster utilizando NIS, la única forma de ver si un usuario tiene una entrada crontab es de acuerdo con la respuesta de Matt / var / spool / cron / tabs.

grep -v "#" -R  /var/spool/cron/tabs

10
2017-08-23 12:13



Me gusta la respuesta simple de una línea arriba:

para el usuario en $ (corte -f1 -d: / etc / passwd); hacer crontab -u $ usuario -l; hecho

Pero Solaris que no tiene el distintivo -u y no imprime al usuario que está verificando, puede modificarlo así:

for user in $(cut -f1 -d: /etc/passwd); do echo User:$user; crontab -l $user 2>&1 | grep -v crontab; done

Obtendrá una lista de usuarios sin los errores lanzados por crontab cuando una cuenta no puede usar cron, etc. Tenga en cuenta que en Solaris, los roles también pueden estar en / etc / passwd (consulte / etc / user_attr).


8
2018-05-03 17:38



Esta secuencia de comandos funcionó para mí en CentOS para enumerar todos los crones en el entorno:

sudo cat /etc/passwd | sed 's/^\([^:]*\):.*$/sudo crontab -u \1 -l 2>\&1/' | grep -v "no crontab for" | sh

8
2018-06-23 06:37