it-swarm.com.de

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

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

Idealerweise möchte ich die Ausgabe in einer Nizza-Spaltenform und auf sinnvolle Weise geordnet haben.

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

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

805
yukondude

Am Ende habe ich ein Skript geschrieben (ich versuche, mir die Feinheiten des Bash-Skripts selbst beizubringen, weshalb Sie hier so etwas wie Perl nicht sehen). Es ist nicht gerade eine einfache Angelegenheit, aber es macht das meiste, was ich brauche. Es verwendet Kyles Vorschlag zum Nachschlagen der Crontabs einzelner Benutzer, befasst sich jedoch auch mit /etc/crontab (einschließlich der von run-parts in /etc/cron.hourly, /etc/cron.daily usw.) und Jobs im Verzeichnis /etc/cron.d. Es nimmt all diese Elemente und fügt 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 ist, damit ich den täglichen Zeitplan 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}"
301
yukondude

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

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

durchläuft jeden Benutzernamen, in dem die Crontab aufgelistet ist. Die Crontabs sind Eigentum der jeweiligen Benutzer, sodass Sie die Crontab eines anderen Benutzers nicht sehen können, ohne diese oder root zu sein.


Bearbeiten Wenn Sie wissen möchten, zu welchem ​​Benutzer eine Crontab gehört, verwenden Sie echo $user

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

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

Bei Redhat 6/7 und Centos befindet sich die Crontab unter /var/spool/cron/.

174
Matt

Dadurch werden alle crontab-Einträge aller Benutzer angezeigt.

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

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

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

als root. Sehr einfach und sehr kurz.

Gibt mir eine Ausgabe wie:

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

==> /var/spool/cron/my_user <==
*/10 1 * * * /path/to/script
28
Jørgen

Eine kleine Verbesserung der Antwort von Kyle Burton mit verbesserter Ausgabeformatierung:

#!/bin/bash
for user in $(cut -f1 -d: /etc/passwd)
do echo $user && crontab -u $user -l
echo " "
done
14
sum
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 Benutzer direkt mit passwd in Berührung kommen, Benutzer ohne cron-Einträge übersprungen werden und für diejenigen, die sie haben, der Benutzername sowie die crontab ausgedruckt werden.

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

13
Mithaldu

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
10
Doris

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

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

Ich mag die einfache Einzeiler-Antwort oben:

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

Solaris, das nicht über das Flag -u verfügt und den Benutzer, den es überprüft, nicht druckt, kann folgendermaßen 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 Rollen in Solaris auch in/etc/passwd enthalten sein können (siehe/etc/user_attr).

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

Liste vom ROOT-Benutzer abrufen.

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

Im Folgenden werden Kommentare, Leerzeilen und Fehler von Benutzern ohne crontab entfernt. Alles, was Ihnen bleibt, ist eine übersichtliche Liste der Benutzer und ihrer Jobs.

Beachten Sie die Verwendung von Sudo in der 2. Zeile. Wenn du bereits root bist, entferne 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).

5
Dale Anderson

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

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

wenn ich möchte, dass mehr Tabulatoren entfernt werden, kann ich Folgendes tun:

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

Wo ist das ein wörtlicher Reiter im sed Ersatzteil.

Es kann systemunabhängiger sein, die Benutzer in /etc/passwd zu durchlaufen und crontab -l -u $user für jeden von ihnen auszuführen.

4
Daniel Papasian

Vielen Dank für dieses sehr nützliche Skript. Ich hatte einige winzige Probleme beim Ausführen auf alten Systemen (Red Hat Enterprise 3, das mit egrep und Tabulatoren in Strings unterschiedlich umgeht) und auf anderen Systemen mit /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 gut, dieses Skript wurde ohne Probleme auf RHEL3, 4, 5 und Debian5 getestet. Hoffe das hilft!

3
jbbarth

sie können für alle Benutzerliste schreiben:

Sudo crontab -u userName -l

,

Sie können auch zu gehen

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

diese Datei listet die Zeitpläne auf

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

Aufbauend auf @Kyle

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

um 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    
2
Ali

Mit Entschuldigung und danke an yukondude.

Ich habe versucht, die Timing-Einstellungen für das einfache Lesen zusammenzufassen, obwohl dies kein perfekter Job ist und ich nicht jeden Freitag oder nur montags anfasse.

Dies ist Version 10 - es ist jetzt:

  • läuft viel viel schneller
  • mit optionalen Fortschrittszeichen können Sie die Geschwindigkeit weiter verbessern.
  • verwendet eine Trennlinie, um Header und Ausgabe zu trennen.
  • ausgaben in einem kompakten Format, wenn alle nicht erfassten Zeitintervalle zusammengefasst werden können.
  • Akzeptiert Jan ... Dec-Deskriptoren für Monate des Jahres
  • Akzeptiert Mo ... So-Deskriptoren für Wochentage
  • versucht, Debian-artige Dummies von Anacron zu behandeln, 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 "command -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

2
david collier

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

for I in `lastlog | grep -v Never | cut -f1 -d' '`; do echo $I ; crontab -l -u $I ; done
2
Monte

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

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

Dies liest /etc/passwd Zeile für Zeile unter Verwendung von : als Feldbegrenzer. Indem wir read -r user _ sagen, lassen wir $user das erste Feld halten und _ den Rest (es ist nur eine Junk-Variable, um Felder zu ignorieren).

Auf diese Weise können wir dann crontab -u mit der Variablen $user aufrufen, die wir zur Sicherheit zitieren (was ist, wenn sie Leerzeichen enthält? In einer solchen Datei ist dies unwahrscheinlich, aber Sie können es nie wissen).

1
fedorqui

Unter Solaris für einen bestimmten bekannten Benutzernamen:

crontab -l username

Alle anderen * Nix benötigen den Modifikator -u:

crontab -u username -l

So rufen Sie wie in den oben genannten Beiträgen alle Jobs eines Benutzers auf einmal unter Solaris ab:

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