Come posso elencare tutti i lavori cron per tutti gli utenti?


858

Esiste un comando o uno script esistente che mi consente di visualizzare contemporaneamente tutti i lavori cron programmati di un sistema * NIX? Mi piacerebbe che includesse tutti i crontab dell'utente, così come /etc/crontab, e qualunque cosa sia dentro /etc/cron.d. Sarebbe anche bello vedere i comandi specifici gestiti da run-partsin /etc/crontab.

Idealmente, vorrei l'output in una bella forma di colonna e ordinato in modo significativo.

Potrei quindi unire questi elenchi da più server per visualizzare il "programma degli eventi" generale.

Stavo per scrivere una sceneggiatura del genere, ma se qualcuno si è già messo nei guai ...


Risposte:


1135

Dovresti eseguirlo come root, ma:

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

passerà in rassegna ogni nome utente elencando il loro crontab. I crontab sono di proprietà dei rispettivi utenti, quindi non sarai in grado di vedere i crontab di un altro utente senza di loro o come root.


Modifica se vuoi sapere a quale utente appartiene un crontab, usaecho $user

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

54
Non funziona quando gli utenti sono definiti in NIS o LDAP. Devi usarefor user in $(getent passwd | cut -f1 -d: ); do echo $user; crontab -u $user -l; done
Hubert Kario l'

10
Aggiornato questo per escludere i commenti e sopprimere i messaggi "no crontab for user ...":for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l 2>/dev/null | grep -v '^#'; done
Jonathan

38
Non sarebbe più facile guardare i file in / var / spool / cron?
graywh,

2
Noi LDAP e / etc / passwd dobbiamo essere sostituiti con il comando getent:for user in $(getent passwd | awk -F : '{print $1}'); do echo $user; crontab -u $user -l; done
Toby Batch

9
Che dire dei cronjobs a /etc/cron.hourly/, /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/...?
Abdull,

309

Ho finito per scrivere una sceneggiatura (sto cercando di insegnare a me stesso i punti più fini della sceneggiatura di Bash, quindi è per questo che non vedi qualcosa come Perl qui). Non è esattamente un affare semplice, ma fa la maggior parte di ciò di cui ho bisogno. Esso utilizza il suggerimento di Kyle per la ricerca di crontabs singoli utenti, ma si occupa anche di /etc/crontab(compresi gli script lanciati da run-partsa /etc/cron.hourly, /etc/cron.daily, etc.) ei posti di lavoro nella /etc/cron.ddirectory. Prende tutti questi e li unisce in un display qualcosa di simile al seguente:

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

Si noti che mostra l'utente e più o meno ordina per ora e minuti in modo che io possa vedere il programma giornaliero.

Finora l'ho provato su Ubuntu, Debian e 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}"

38
Niente, ma non ha fatto nulla per i lavori cron di sistema in / etc / crontab e /etc/cron.d/. Trattare con quelli e formattare tutto alla fine è ciò che fa la mia sceneggiatura.
yukondude,

10
yukondude - dovresti considerare di metterlo su github, anche solo come sostanza.
Kyle Burton,

3
Ho provato a copiare incolla ed eseguirlo, ma non riesce: showcrons.sh: riga 59: errore di sintassi vicino al token imprevisto <' showcrons.sh: line 59: fatto <<(cut --fields = 1 --delimiter =: / etc / passwd) '
Fraggle

2
@KyleBurton Sembra che almeno 8 persone stiano già copiando questo, gist.github.com/gists/…
Zitrax,

9
Avvertenza: in questo script mancano gli eventi di/etc/anacrontab
ck_

191

Sotto Ubuntu o debian, puoi visualizzare crontab da /var/spool/cron/crontabs/ e quindi un file per ogni utente è lì. Questo è ovviamente solo per i crontab specifici dell'utente.

Per Redhat 6/7 e Centos, il crontab è sotto /var/spool/cron/.


7
Funziona anche su RedHat (/ var / spool / cron) ed è più facile che scrivere / eseguire uno script soprattutto se stai usando qualcosa come Ldap per gestire gli account. +1
user49913

6
Questo mi è stato molto più utile di qualsiasi altra risposta. Questo metodo consente di visualizzare i crontab degli utenti che non esistono più, dandoti TUTTI i lavori cron richiesti dall'OP.
Andrew Ensley,

1
Un altro vantaggio di questo metodo: il mio server utilizza LDAP, quindi la maggior parte degli utenti non è presente /etc/passwd. IMO questa dovrebbe essere la risposta accettata, piuttosto che tutte le soluzioni di forza bruta.
Mikkel,

1
Bene con Suse Linux qui.
Bret,

Grazie, questo vale anche per l'installazione di AWS EC2, questa informazione è stata molto utile!
Ivan Marjanovic,

34

Questo mostrerà tutte le voci crontab di tutti gli utenti.

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

30

Dipende dalla tua versione di Linux ma io uso:

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

come radice. Molto semplice e molto corto.

Mi dà un output come:

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

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

4
Utilizzare tail -n +1 /var/spool/cron/*per elencare tutto il contenuto dei file.
Hans Ginzel,

4
... o sudo sh -c 'tail -n +1 /var/spool/cron/*'se non vuoi diventare root. Il mio disturbo ossessivo compulsivo mi ha costretto a indagare sul motivo per cui non potevo eseguire questo comando come scritto. Questo perché gli utenti normali non hanno accesso a / var / spool / cron dir e il glob veniva interpretato come un personaggio letterale da star, che ovviamente non esiste.
Dale Anderson,

in alternativa, cd /var/spool/cron/cron/ && grep . *stamperà anche il nome utente corrispondente davanti a ogni cron job
Jakub Kukul,


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

Questo evita di fare casini con passwd direttamente, salta gli utenti che non hanno voci cron e per quelli che li hanno stampa il nome utente e il loro crontab.

Per lo più lasciandolo qui, quindi posso trovarlo più tardi nel caso in cui dovessi mai cercarlo di nuovo.


1
Elenca anche gli utenti LDAP non presenti in /etc/passwd. La soluzione di Matt sopra è più appropriata per questa particolare situazione, ma è bene sapere che il comando esiste.
Mikkel,

11

Se controlli un cluster usando NIS, l'unico modo per vedere se un utente ha una voce crontab è la risposta di Matt / var / spool / cron / tabs.

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

11

Per ottenere l'elenco dall'utente ROOT.

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

10

Questo script ha funzionato per me in CentOS per elencare tutti i croni nell'ambiente:

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

2
Eccezionale! Ho aggiunto una piccola variazione per vedere a quale utente si trova il lavoro cron e ho messo cat /etc/passwd | sed 's/^\([^:]*\):.*$/echo "\ncrontab for \1:"; sudo crontab -u \1 -l 2>\&1/' | grep -v "no crontab for" | shun po 'di spazio tra i risultati: fa risparmiare un po' di tempo
jamil

9

Mi piace la semplice risposta di una riga sopra:

per l'utente in $ (cut -f1 -d: / etc / passwd); crontab -u $ user -l; fatto

Ma Solaris che non ha il flag -u e non stampa l'utente che sta controllando, è possibile modificarlo in questo modo:

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

Verrà visualizzato un elenco di utenti senza gli errori generati da crontab quando un account non è autorizzato a utilizzare cron ecc. Tenere presente che in Solaris i ruoli possono essere anche in / etc / passwd (vedere / etc / user_attr).



Freddo. TIL non usare per.
squarismo


7

Quanto segue rimuove commenti, righe vuote ed errori dagli utenti senza crontab. Tutto ciò che ti rimane è un chiaro elenco di utenti e dei loro lavori.

Si noti l'uso di sudonella seconda riga. Se sei già root, rimuovilo.

for USER in $(cut -f1 -d: /etc/passwd); do \
USERTAB="$(sudo crontab -u "$USER" -l 2>&1)";  \
FILTERED="$(echo "$USERTAB"| grep -vE '^#|^$|no crontab for|cannot use this program')";  \
if ! test -z "$FILTERED"; then  \
echo "# ------ $(tput bold)$USER$(tput sgr0) ------";  \
echo "$FILTERED";  \
echo "";  \
fi;  \
done

Esempio di output:

# ------ root ------
0 */6 * * * /usr/local/bin/disk-space-notify.sh
45 3 * * * /opt/mysql-backups/mysql-backups.sh
5 7 * * * /usr/local/bin/certbot-auto renew --quiet --no-self-upgrade

# ------ sammy ------
55 * * * * wget -O - -q -t 1 https://www.example.com/cron.php > /dev/null

Lo uso su Ubuntu (dal 12 al 16) e Red Hat (dal 5 al 7).


5

Dipende dalla tua versione di cron. Usando Vixie cron su FreeBSD, posso fare qualcosa del genere:

(cd /var/cron/tabs && grep -vH ^# *) 

se lo voglio più tabulato, potrei fare qualcosa del genere:

(cd /var/cron/tabs && grep -vH ^# * | sed "s/:/      /")

Dove è una scheda letterale nella parte di sostituzione sed.

Potrebbe essere più indipendente dal sistema eseguire il loop degli utenti /etc/passwde farlo crontab -l -u $userper ciascuno di essi.


4

Grazie per questo script molto utile. Ho avuto alcuni piccoli problemi eseguendolo su vecchi sistemi (Red Hat Enterprise 3, che gestiscono egrep e tabs nelle stringhe in modo diverso), e altri sistemi con nulla in /etc/cron.d/ (lo script si è quindi concluso con un errore). Quindi ecco una patch per farlo funzionare in questi casi:

2a3,4
> #See:  http://stackoverflow.com/questions/134906/how-do-i-list-all-cron-jobs-for-all-users
>
27c29,30
<         match=$(echo "${line}" | egrep -o 'run-parts (-{1,2}\S+ )*\S+')
---
>         #match=$(echo "${line}" | egrep -o 'run-parts (-{1,2}\S+ )*\S+')
>         match=$(echo "${line}" | egrep -o 'run-parts.*')
51c54,57
< cat "${CRONDIR}"/* | clean_cron_lines >>"${temp}"  # */ <not a comment>
---
> sys_cron_num=$(ls /etc/cron.d | wc -l | awk '{print $1}')
> if [ "$sys_cron_num" != 0 ]; then
>       cat "${CRONDIR}"/* | clean_cron_lines >>"${temp}"  # */ <not a comment>
> fi
67c73
<     sed "1i\mi\th\td\tm\tw\tuser\tcommand" |
---
>     sed "1i\mi${tab}h${tab}d${tab}m${tab}w${tab}user${tab}command" |

Non sono davvero sicuro che i cambiamenti nel primo egrep siano una buona idea, ma bene, questo script è stato testato su RHEL3,4,5 e Debian5 senza alcun problema. Spero che sia di aiuto!


3

Costruito in cima a @Kyle

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

per evitare i commenti di solito nella parte superiore di / etc / passwd,

E su macosx

for user in $(dscl . -list /users | cut -f1 -d:); do echo $user; crontab -u $user -l; done    

3
Non dovresti grep -v '^#'invece di fare affidamento sul numero magico 11?
RR-

1
Le distribuzioni Red Hat / CentOS non scrivono i suggerimenti utili all'inizio del crontab di un utente, quindi tagliare le prime 11 righe ne cancellerà il contenuto. Stessa cosa se un utente Ubuntu ha modificato il proprio crontab e rimosso tutta la mano.
Dale Anderson,



3

puoi scrivere per tutto l'elenco utenti:

sudo crontab -u userName -l

,

Puoi anche andare a

cd /etc/cron.daily/
ls -l
cat filename

questo file elencherà i programmi

cd /etc/cron.d/
ls -l
cat filename

3

Con scuse e grazie a yukondude.

Ho provato a sintetizzare le impostazioni di temporizzazione per una facile lettura, anche se non è un lavoro perfetto e non tocco "tutti i venerdì" o "solo sulle cose del lunedì".

Questa è la versione 10 - ora:

  • corre molto più veloce
  • ha caratteri di avanzamento opzionali in modo da poter migliorare ulteriormente la velocità.
  • utilizza una linea di divisione per separare intestazione e output.
  • uscite in un formato compatto quando tutti gli intervalli di temporizzazione incontrati possono essere riassunti.
  • Accetta i descrittori Jan ... Dec per i mesi dell'anno
  • Accetta Mon ... Descrittori Sun per i giorni della settimana
  • prova a gestire il dummying-up debian-style di anacron quando manca
  • tenta di gestire le linee crontab che eseguono un file dopo aver eseguito il test preliminare dell'esecuzione usando "[-x ...]"
  • prova a gestire le righe crontab che eseguono un file dopo aver eseguito il test preliminare dell'esecuzione usando "command -v"
  • consente l'uso di intervalli e liste di intervalli.
  • supporta l'utilizzo di parti run in file crontab specifici per utente / var / spool.

Ora sto pubblicando la sceneggiatura per intero qui.

https://gist.github.com/myshkin-uk/d667116d3e2d689f23f18f6cd3c71107


2

Poiché si tratta di /etc/passwdeseguire il looping di un file ( ) e di eseguire un'azione, mi manca l'approccio corretto su Come posso leggere un file (flusso di dati, variabile) riga per riga (e / o campo per campo )? :

while IFS=":" read -r user _
do
   echo "crontab for user ${user}:"
   crontab -u "$user" -l
done < /etc/passwd

Questo legge /etc/passwdriga per riga usando :come delimitatore di campo. Dicendo read -r user _, prendiamo $useril primo campo e_ il resto (è solo una variabile spazzatura per ignorare i campi).

In questo modo, possiamo quindi chiamare crontab -uutilizzando la variabile $user, che citiamo per sicurezza (cosa succede se contiene spazi? È improbabile in tale file, ma non si può mai sapere).


1

Su Solaris, per un nome utente noto in particolare:

crontab -l username

Tutti gli altri * Nix avranno bisogno di -umodificatori:

crontab -u username -l

Per ottenere tutti i lavori degli utenti contemporaneamente su Solaris, proprio come gli altri post precedenti:

for user in $(cut -f1 -d: /etc/passwd); do crontab -l $user 2>/dev/null; done

-1

Per me guardare / var / spool / cron / crontabs è il modo migliore


2
questo è stato risposto prima
bummi

-2

Questo script genera Crontab in un file ed elenca anche tutti gli utenti che confermano quelli che non hanno voci crontab:

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

// RobFrost, sei sicuro che questo script, come scritto qui, funzioni costantemente?
Nathan Basanese,

Vedi Perché non leggi le righe con "for" . Inoltre, questo è stato risposto molte volte prima di pubblicare questo.
fedorqui "SO smettere di danneggiare" il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.