Wie liste ich alle Cron-Jobs für alle Benutzer auf?

858

Gibt es einen Befehl oder ein vorhandenes Skript, mit dem ich alle geplanten Cron-Jobs eines * NIX-Systems gleichzeitig anzeigen kann? Ich möchte es alle Benutzer crontabs enthalten, sowie /etc/crontab, und was ist in /etc/cron.d. Es wäre auch schön zu sehen, welche spezifischen Befehle von run-partsin ausgeführt werden /etc/crontab.

Idealerweise möchte ich die Ausgabe in einer schönen Spaltenform und auf sinnvolle Weise sortieren.

Ich könnte diese Einträge dann von mehreren Servern zusammenführen, um den gesamten "Zeitplan der Ereignisse" anzuzeigen.

Ich wollte gerade selbst ein solches Skript schreiben, aber wenn sich schon jemand die Mühe gemacht hat ...

Yukondude
quelle
2
Ähnliche Frage zu Unix SE: unix.stackexchange.com/questions/7053/…
maxschlepzig

Antworten:

1135

Sie müssten dies als root ausführen, aber:

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

wird jeden Benutzernamen durchlaufen, der die Crontab auflistet. Die Crontabs gehören den jeweiligen Benutzern, sodass Sie die Crontab eines anderen Benutzers nicht sehen können, ohne sie oder root zu sein.


Bearbeiten Sie, wenn Sie wissen möchten, zu welchem ​​Benutzer eine Crontab gehörtecho $user

for user in $(cut -f1 -d: /etc/passwd); do echo $user; crontab -u $user -l; done
Kyle Burton
quelle
54
Funktioniert nicht, wenn die Benutzer in NIS oder LDAP definiert sind. Sie müssen verwendenfor user in $(getent passwd | cut -f1 -d: ); do echo $user; crontab -u $user -l; done
Hubert Kario
10
Dies wurde aktualisiert, um Kommentare auszuschließen und Nachrichten "Keine Crontab für Benutzer ..." zu unterdrücken:for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l 2>/dev/null | grep -v '^#'; done
Jonathan
38
Wäre es nicht einfacher, die Dateien in / var / spool / cron anzusehen?
Graywh
2
Wir uns LDAP und / etc / passwd müssen durch den Befehl getent ersetzt werden:for user in $(getent passwd | awk -F : '{print $1}'); do echo $user; crontab -u $user -l; done
Toby Batch
9
Was ist mit dem cronjobs in /etc/cron.hourly/, /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/...?
Abdull
309

Am Ende habe ich ein Skript geschrieben (ich versuche mir die Feinheiten des Bash-Skripts beizubringen, deshalb sehen Sie hier so etwas wie Perl nicht). Es ist nicht gerade eine einfache Angelegenheit, aber es macht das meiste, was ich brauche. Es nutzt Kyle Vorschlag für einzelne Benutzer crontabs aufzublicken, sondern befasst sich auch mit /etc/crontab(einschließlich der Start - Skripte von run-partsin /etc/cron.hourly, /etc/cron.dailyusw.) und die Arbeitsplätze im /etc/cron.dVerzeichnis. Es nimmt all diese und führt sie zu einer Anzeige wie der folgenden zusammen:

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

Beachten Sie, dass es den Benutzer anzeigt und mehr oder weniger nach Stunde und Minute sortiert, damit ich den Tagesplan sehen kann.

Bisher habe ich es auf Ubuntu, Debian und Red Hat AS getestet.

#!/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
quelle
38
Nichts, aber es hat nichts gegen die System-Cron-Jobs in / etc / crontab und /etc/cron.d/ getan. Mit diesen umzugehen und alles am Ende zu formatieren, ist das, was mein Skript tut.
Yukondude
10
yukondude - du solltest darüber nachdenken, dies auf github zu setzen, auch nur als Kern.
Kyle Burton
3
Es wurde versucht, das Einfügen zu kopieren und auszuführen, aber es schlägt fehl: showcrons.sh: Zeile 59: Syntaxfehler in der Nähe des unerwarteten Tokens <' showcrons.sh: line 59: erledigt << (cut --fields = 1 --delimiter =: / etc / passwd) '
Fraggle
2
@ KyleBurton Es scheinen mindestens 8 Gists dies bereits zu kopieren, gist.github.com/gists/…
Zitrax
9
Warnung: In diesem Skript fehlen Ereignisse von/etc/anacrontab
ck_
191

Unter Ubuntu oder Debian können Sie crontab von anzeigen, /var/spool/cron/crontabs/und dann befindet sich dort eine Datei für jeden Benutzer. Das gilt natürlich nur für benutzerspezifische Crontab's.

Für Redhat 6/7 und Centos ist die Crontab unter /var/spool/cron/.

caot
quelle
7
Dies funktioniert auch unter RedHat (/ var / spool / cron) und ist einfacher als das Schreiben / Ausführen eines Skripts, insbesondere wenn Sie zum Verwalten von Konten etwas wie Ldap verwenden. +1
user49913
6
Dies war für mich viel hilfreicher als jede andere Antwort. Mit dieser Methode können Sie die Crontabs von Benutzern anzeigen, die nicht mehr vorhanden sind, und ALLE Cron-Jobs erhalten, wie vom OP angefordert.
Andrew Ensley
1
Ein weiterer Vorteil dieser Methode: Mein Server verwendet LDAP, sodass die meisten Benutzer nicht angemeldet sind /etc/passwd. IMO sollte dies die akzeptierte Antwort sein und nicht alle Brute-Force-Lösungen.
Mikkel
1
Gut mit Suse Linux hier.
Bret
Thx, dies gilt auch für AWS EC2 instace, diese Info war sehr hilfreich!
Ivan Marjanovic
34

Dies zeigt alle Crontab-Einträge aller Benutzer an.

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

Hängt von deiner Linux-Version ab, aber ich benutze:

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

als Wurzel. Sehr einfach und sehr kurz.

Gibt mir Ausgabe wie:

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

==> /var/spool/cron/my_user <==
*/10 1 * * * /path/to/script
Jørgen
quelle
4
Verwenden Sie tail -n +1 /var/spool/cron/*diese Option, um den gesamten Inhalt der Dateien aufzulisten.
Hans Ginzel
4
... oder sudo sh -c 'tail -n +1 /var/spool/cron/*'wenn du nicht root werden willst. Meine OCD zwang mich zu untersuchen, warum ich diesen Befehl nicht wie geschrieben ausführen konnte. Dies lag daran, dass reguläre Benutzer keinen Zugriff auf / var / spool / cron dir haben und der Glob als wörtliches Sternzeichen interpretiert wurde, das offensichtlich nicht existiert.
Dale Anderson
Alternativ cd /var/spool/cron/cron/ && grep . *wird auch der entsprechende Benutzername vor jedem Cron-Job
gedruckt
15

Eine kleine Verfeinerung von Kyle Burtons Antwort mit verbesserter Ausgabeformatierung:

#!/bin/bash
for user in $(cut -f1 -d: /etc/passwd)
do echo $user && crontab -u $user -l
echo " "
done
Summe
quelle
Siehe Warum Sie keine Zeilen mit "für" lesen .
Fedorqui 'SO hör auf zu schaden'
14
getent passwd | cut -d: -f1 | perl -e'while(<>){chomp;$l = `crontab -u $_ -l 2>/dev/null`;print "$_\n$l\n" if $l}'

Dadurch wird vermieden, dass Sie direkt mit passwd herumspielen, Benutzer überspringen, die keine Cron-Einträge haben, und für diejenigen, die sie haben, werden der Benutzername sowie deren Crontab ausgedruckt.

Meistens hier, damit ich es später finden kann, falls ich jemals wieder danach suchen muss.

Mithaldu
quelle
1
Außerdem werden LDAP-Benutzer aufgelistet, die nicht in vorhanden sind /etc/passwd. Die obige Lösung von Matt ist für diese spezielle Situation besser geeignet, aber es ist gut zu wissen, dass der Befehl vorhanden ist.
Mikkel
11

Wenn Sie einen Cluster mit NIS überprüfen, können Sie nur anhand von Matts Antwort / var / spool / cron / tabs feststellen, ob ein Benutzer einen Crontab-Eintrag hat.

grep -v "#" -R  /var/spool/cron/tabs
Doris
quelle
11

Um eine Liste vom ROOT-Benutzer zu erhalten.

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

Dieses Skript hat in CentOS für mich funktioniert, um alle Cron in der Umgebung aufzulisten:

sudo cat /etc/passwd | sed 's/^\([^:]*\):.*$/sudo crontab -u \1 -l 2>\&1/' | grep -v "no crontab for" | sh
Sam T.
quelle
2
Genial! Ich habe eine kleine Variation hinzugefügt, um zu sehen, unter welchem ​​Benutzer sich der Cron-Job befindet, und etwas Platz zwischen den Ergebnissen cat /etc/passwd | sed 's/^\([^:]*\):.*$/echo "\ncrontab for \1:"; sudo crontab -u \1 -l 2>\&1/' | grep -v "no crontab for" | sh
eingefügt
9

Ich mag die einfache Einzeiler-Antwort oben:

für Benutzer in $ (cut -f1 -d: / etc / passwd); do crontab -u $ user -l; erledigt

Solaris, das nicht über das Flag -u verfügt und den zu überprüfenden Benutzer nicht druckt, kann wie folgt geändert werden:

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

Sie erhalten eine Liste der Benutzer ohne die von crontab ausgelösten Fehler, wenn ein Konto cron usw. nicht verwenden darf. Beachten Sie, dass sich Rollen in Solaris auch in / etc / passwd befinden können (siehe / etc / user_attr).

Squarismus
quelle
1
Siehe Warum Sie keine Zeilen mit "für" lesen .
Fedorqui 'SO hör auf zu schaden'
Cool. Bis nicht zu verwenden.
Squarism
8
for user in $(cut -f1 -d: /etc/passwd); 
do 
    echo $user; crontab -u $user -l; 
done
Indra Bhushan Kumar
quelle
Siehe Warum Sie keine Zeilen mit "für" lesen . Diese Antwort wiederholt auch nur andere.
Fedorqui 'SO hör auf zu schaden'
7

Im Folgenden werden Kommentare, Leerzeilen und Fehler von Benutzern ohne Crontab entfernt. Sie haben nur noch eine übersichtliche Liste der Benutzer und ihrer Jobs.

Beachten Sie die Verwendung von sudoin der 2. Zeile. Wenn Sie bereits root sind, entfernen Sie das.

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

Beispielausgabe:

# ------ 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

Ich benutze dies auf Ubuntu (12 bis 16) und Red Hat (5 bis 7).

Dale Anderson
quelle
5

Hängt von Ihrer Version von cron ab. Mit Vixie cron unter FreeBSD kann ich Folgendes tun:

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

Wenn ich möchte, dass mehr Tabs entfernt werden, kann ich Folgendes tun:

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

Wo das eine wörtliche Registerkarte im sed Ersatzteil ist.

Es kann systemunabhängiger sein, die Benutzer zu durchlaufen /etc/passwdund crontab -l -u $userfür jeden von ihnen zu tun .

Daniel Papasian
quelle
4

Vielen Dank für dieses sehr nützliche Skript. Ich hatte einige winzige Probleme beim Ausführen auf alten Systemen (Red Hat Enterprise 3, die unterschiedliche egrep und Tabs in Zeichenfolgen verarbeiten) und anderen Systemen mit nichts in /etc/cron.d/ (das Skript endete dann mit einem Fehler). Hier ist ein Patch, mit dem es in solchen Fällen funktioniert:

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" |

Ich bin mir nicht sicher, ob die Änderungen im ersten egrep eine gute Idee sind, aber dieses Skript wurde problemlos auf RHEL3,4,5 und Debian5 getestet. Hoffe das hilft!

jbbarth
quelle
3

Aufbauend auf @Kyle

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

um die Kommentare zu vermeiden, die normalerweise oben in / etc / passwd stehen,

Und auf Macosx

for user in $(dscl . -list /users | cut -f1 -d:); do echo $user; crontab -u $user -l; done    
Ali
quelle
3
Solltest du dich nicht grep -v '^#auf eine magische Zahl verlassen 11?
11.
1
Red Hat / CentOS-Distributionen schreiben nicht die hilfreichen Hinweise zu Beginn der Crontab eines Benutzers. Wenn Sie also die ersten 11 Zeilen abschneiden, wird der Inhalt gelöscht. Das Gleiche gilt, wenn ein Ubuntu-Benutzer seine eigene Crontab bearbeitet und alle Handgriffe entfernt hat.
Dale Anderson
Siehe Warum Sie keine Zeilen mit "für" lesen .
Fedorqui 'SO hör auf zu schaden'
3

Ich denke, ein besserer Einzeiler wäre unten. Wenn Sie beispielsweise Benutzer in NIS oder LDAP haben, befinden sich diese nicht in / etc / passwd. Dadurch erhalten Sie die Crontabs aller Benutzer, die sich angemeldet haben.

for I in `lastlog | grep -v Never | cut -f1 -d' '`; do echo $I ; crontab -l -u $I ; done
Monte
quelle
Siehe Warum Sie keine Zeilen mit "für" lesen .
Fedorqui 'SO hör auf zu schaden'
3

Sie können für alle Benutzerlisten schreiben:

sudo crontab -u userName -l

,

Sie können auch gehen

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

Diese Datei listet die Zeitpläne auf

cd /etc/cron.d/
ls -l
cat filename
rkoots
quelle
3

Mit Entschuldigung und Dank an Yukondude.

Ich habe versucht, die Timing-Einstellungen für ein einfaches Lesen zusammenzufassen, obwohl es kein perfekter Job ist, und ich berühre nicht "jeden Freitag" oder "nur montags".

Dies ist Version 10 - jetzt:

  • läuft viel viel schneller
  • verfügt über optionale Fortschrittszeichen, sodass Sie die Geschwindigkeit weiter verbessern können.
  • verwendet eine Trennlinie, um Header und Ausgabe zu trennen.
  • Ausgaben in einem kompakten Format, wenn alle Zeitintervalle zusammengefasst sind.
  • Akzeptiert Jan ... Dec-Deskriptoren für Monate des Jahres
  • Akzeptiert Mon ... Sun-Deskriptoren für Wochentage
  • versucht, das Debian-up von Anacron im Debian-Stil zu handhaben, wenn es fehlt
  • versucht, mit Crontab-Zeilen umzugehen, die eine Datei ausführen, nachdem die Ausführbarkeit mit "[-x ...]" vorab getestet wurde.
  • versucht, mit Crontab-Zeilen umzugehen, die eine Datei ausführen, nachdem die Ausführbarkeit mit "Befehl -v" vorab getestet wurde.
  • ermöglicht die Verwendung von Intervallbereichen und Listen.
  • unterstützt die Verwendung von Run-Parts in benutzerspezifischen / var / spool-Crontab-Dateien.

Ich veröffentliche das Skript jetzt vollständig hier.

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

David Collier
quelle
2

Da es darum geht, eine Datei ( /etc/passwd) zu durchlaufen und eine Aktion auszuführen, fehlt mir der richtige Ansatz, wie ich eine Datei (Datenstrom, Variable) Zeile für Zeile (und / oder Feld für Feld) lesen kann )? ::

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

Dies liest /etc/passwdZeile für Zeile unter Verwendung :als Feldtrennzeichen. Indem read -r user _wir sagen , $userhalten wir das erste Feld und _den Rest fest (es ist nur eine Junk-Variable, um Felder zu ignorieren).

Auf diese Weise können wir dann crontab -udie Variable aufrufen $user, die wir aus Sicherheitsgründen zitieren (was ist, wenn sie Leerzeichen enthält? In einer solchen Datei ist dies unwahrscheinlich, aber Sie können es nie erfahren).

fedorqui 'SO hör auf zu schaden'
quelle
1

Unter Solaris für einen bestimmten bekannten Benutzernamen:

crontab -l username

Alle anderen * Nix benötigen -uModifikator:

crontab -u username -l

So erhalten Sie alle Jobs eines Benutzers gleichzeitig in Solaris, ähnlich wie in anderen oben genannten Beiträgen:

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

Für mich ist ein Blick auf / var / spool / cron / crontabs der beste Weg

Nic0
quelle
2
Dies wurde vor
Bummi
-2

Dieses Skript gibt die Crontab in eine Datei aus und listet auch alle Benutzer auf, die diejenigen bestätigen, die keinen Crontab-Eintrag haben:

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
Rob Frost
quelle
//, RobFrost, sind Sie sicher, dass dieses Skript, wie hier geschrieben, konsistent funktioniert?
Nathan Basanese
Siehe Warum Sie keine Zeilen mit "für" lesen . Auch dies wurde viele Male beantwortet, bevor Sie dieses gepostet haben.
Fedorqui 'SO hör auf zu schaden'