Comment répertorier tous les travaux cron pour tous les utilisateurs?

858

Existe-t-il une commande ou un script existant qui me permettra de visualiser tous les travaux cron planifiés d'un système * NIX à la fois? J'aimerais qu'il inclue tous les crontabs utilisateur, ainsi que /etc/crontabtout ce qui s'y trouve /etc/cron.d. Il serait également intéressant de voir les commandes spécifiques exécutées par run-partsdans /etc/crontab.

Idéalement, j'aimerais que la sortie soit sous forme de colonne agréable et ordonnée de manière significative.

Je pouvais ensuite fusionner ces listes à partir de plusieurs serveurs pour afficher le "calendrier des événements" global.

J'étais sur le point d'écrire un tel script moi-même, mais si quelqu'un a déjà eu des ennuis ...

yukondude
la source
2
Question similaire sur Unix SE: unix.stackexchange.com/questions/7053/…
maxschlepzig

Réponses:

1135

Vous devrez l'exécuter en tant que root, mais:

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

fera une boucle sur chaque nom d'utilisateur répertoriant leur crontab. Les crontabs appartiennent aux utilisateurs respectifs, vous ne pourrez donc pas voir la crontab d'un autre utilisateur sans être eux ou root.


Modifiez si vous voulez savoir à quel utilisateur appartient un crontab, utilisezecho $user

for user in $(cut -f1 -d: /etc/passwd); do echo $user; crontab -u $user -l; done
Kyle Burton
la source
54
Ne fonctionne pas lorsque les utilisateurs sont définis dans NIS ou LDAP. Vous devez utiliserfor user in $(getent passwd | cut -f1 -d: ); do echo $user; crontab -u $user -l; done
Hubert Kario
10
Mis à jour pour exclure les commentaires et supprimer les messages "pas de crontab pour l'utilisateur ...":for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l 2>/dev/null | grep -v '^#'; done
Jonathan
38
Ne serait-il pas plus facile de regarder les fichiers dans / var / spool / cron?
graywh
2
Nous nous LDAP et / etc / passwd doit être remplacé par la commande getent:for user in $(getent passwd | awk -F : '{print $1}'); do echo $user; crontab -u $user -l; done
Toby Batch
9
Qu'en est- il des cronjobs dans /etc/cron.hourly/, /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/...?
Abdull
309

J'ai fini par écrire un script (j'essaie de m'enseigner les points les plus fins du script bash, c'est pourquoi vous ne voyez pas quelque chose comme Perl ici). Ce n'est pas exactement une simple affaire, mais elle fait la plupart de ce dont j'ai besoin. Il utilise la suggestion de Kyle pour rechercher des crontabs des utilisateurs individuels, mais traite aussi /etc/crontab(y compris les scripts lancés par run-partsdans /etc/cron.hourly, /etc/cron.dailyetc.) et les emplois dans le /etc/cron.drépertoire. Il prend tout cela et les fusionne dans un affichage quelque chose comme ceci:

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

Notez qu'il montre l'utilisateur et trie plus ou moins par heure et minute afin que je puisse voir le programme quotidien.

Jusqu'à présent, je l'ai testé sur Ubuntu, Debian et 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
la source
38
Rien, mais cela n'a rien fait pour les tâches cron du système dans / etc / crontab et /etc/cron.d/. Le traitement de ceux-ci, et le formatage de tout à la fin, est ce que fait mon script.
yukondude
10
yukondude - vous devriez envisager de mettre cela sur github, même juste comme un gist.
Kyle Burton
3
J'ai essayé de copier-coller et de l'exécuter, mais il échoue: showcrons.sh: ligne 59: erreur de syntaxe près du jeton inattendu <' showcrons.sh: line 59: fait <<(cut --fields = 1 --delimiter =: / etc / passwd) '
Fraggle
2
@KyleBurton Il semble qu'au moins 8 gists
Zitrax
9
Avertissement: il manque des événements dans ce script à partir du/etc/anacrontab
ck_
191

Sous Ubuntu ou debian, vous pouvez afficher crontab par /var/spool/cron/crontabs/ puis un fichier pour chaque utilisateur s'y trouve. Bien sûr, cela ne concerne que les crontab spécifiques à l'utilisateur.

Pour Redhat 6/7 et Centos, le crontab est sous /var/spool/cron/.

caot
la source
7
Cela fonctionne également sur RedHat (/ var / spool / cron) et est plus facile que d'écrire / exécuter un script, surtout si vous utilisez quelque chose comme Ldap pour gérer les comptes. +1
user49913
6
Cela m'a été beaucoup plus utile que toutes les autres réponses. Cette méthode vous permet d'afficher les crontabs des utilisateurs qui n'existent plus également, vous donnant TOUTES les tâches cron demandées par l'OP.
Andrew Ensley
1
Un autre avantage de cette méthode: mon serveur utilise LDAP, donc la plupart des utilisateurs n'y sont pas /etc/passwd. OMI, cela devrait être la réponse acceptée, plutôt que toutes les solutions de force brute.
Mikkel
1
Bon avec Suse Linux ici.
Bret
Thx, cela est également vrai pour AWS EC2 instace, ces informations ont été très utiles!
Ivan Marjanovic
34

Cela montrera toutes les entrées crontab de tous les utilisateurs.

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

Dépend de votre version linux mais j'utilise:

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

en tant que root. Très simple et très court.

Me donne une sortie comme:

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

==> /var/spool/cron/my_user <==
*/10 1 * * * /path/to/script
Jørgen
la source
4
Utilisez tail -n +1 /var/spool/cron/*pour lister tout le contenu des fichiers.
Hans Ginzel
4
... ou sudo sh -c 'tail -n +1 /var/spool/cron/*'si vous ne voulez pas devenir root. Mon trouble obsessionnel-compulsif m'a obligé à rechercher pourquoi je ne pouvais pas sudo cette commande comme écrit. C'est parce que les utilisateurs réguliers n'ont pas accès au répertoire / var / spool / cron et que le glob était interprété comme un caractère étoile littéral, qui n'existe évidemment pas.
Dale Anderson
alternativement, cd /var/spool/cron/cron/ && grep . *imprimera également le nom d'utilisateur correspondant devant chaque tâche cron
Jakub Kukul
15

Un petit raffinement de la réponse de Kyle Burton avec un formatage de sortie amélioré:

#!/bin/bash
for user in $(cut -f1 -d: /etc/passwd)
do echo $user && crontab -u $user -l
echo " "
done
somme
la source
Voir Pourquoi vous ne lisez pas les lignes avec "pour" .
fedorqui 'SO arrête de nuire'
14
getent passwd | cut -d: -f1 | perl -e'while(<>){chomp;$l = `crontab -u $_ -l 2>/dev/null`;print "$_\n$l\n" if $l}'

Cela évite de jouer directement avec passwd, ignore les utilisateurs qui n'ont pas d'entrées cron et pour ceux qui les ont, il imprime le nom d'utilisateur ainsi que leur crontab.

La plupart du temps, je le laisse ici pour que je puisse le trouver plus tard au cas où j'aurais besoin de le rechercher à nouveau.

Mithaldu
la source
1
Il répertorie également les utilisateurs LDAP non présents dans /etc/passwd. La solution de Matt ci-dessus est plus appropriée à cette situation particulière, mais il est bon de savoir que la commande existe.
Mikkel
11

Si vous vérifiez un cluster à l'aide de NIS, la seule façon de voir si un utilisateur a une entrée crontab selon la réponse / var / spool / cron / tab de Matt.

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

Pour obtenir la liste des utilisateurs ROOT.

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

Ce script a fonctionné pour moi dans CentOS pour répertorier tous les crons de l'environnement:

sudo cat /etc/passwd | sed 's/^\([^:]*\):.*$/sudo crontab -u \1 -l 2>\&1/' | grep -v "no crontab for" | sh
Sam T
la source
2
Impressionnant! J'ai ajouté une petite variation pour voir à quel utilisateur le travail cron est sous et j'ai mis un peu d'espace entre les résultats: fait cat /etc/passwd | sed 's/^\([^:]*\):.*$/echo "\ncrontab for \1:"; sudo crontab -u \1 -l 2>\&1/' | grep -v "no crontab for" | shgagner un peu de temps
jamil
9

J'aime la réponse simple à une ligne ci-dessus:

pour l'utilisateur dans $ (cut -f1 -d: / etc / passwd); do crontab -u $ user -l; terminé

Mais Solaris qui n'a pas l'indicateur -u et n'imprime pas l'utilisateur qu'il vérifie, vous pouvez le modifier comme suit:

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

Vous obtiendrez une liste d'utilisateurs sans les erreurs générées par crontab lorsqu'un compte n'est pas autorisé à utiliser cron, etc. Soyez conscient que dans Solaris, les rôles peuvent également se trouver dans / etc / passwd (voir / etc / user_attr).

squarisme
la source
1
Voir Pourquoi vous ne lisez pas les lignes avec "pour" .
fedorqui 'SO arrête de nuire'
Cool. TIL à ne pas utiliser pour.
squarisme
8
for user in $(cut -f1 -d: /etc/passwd); 
do 
    echo $user; crontab -u $user -l; 
done
indra bhushan kumar
la source
Voir Pourquoi vous ne lisez pas les lignes avec "pour" . De plus, cette réponse ne fait que répéter les autres.
fedorqui 'SO arrête de nuire'
7

Les éléments suivants suppriment les commentaires, les lignes vides et les erreurs des utilisateurs sans crontab. Il ne vous reste qu'une liste claire des utilisateurs et de leurs tâches.

Notez l'utilisation de sudodans la 2ème ligne. Si vous êtes déjà root, supprimez-le.

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

Exemple de sortie:

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

Je l'utilise sur Ubuntu (12 à 16) et Red Hat (5 à 7).

Dale Anderson
la source
5

Cela dépend de votre version de cron. En utilisant Vixie cron sur FreeBSD, je peux faire quelque chose comme ceci:

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

si je veux supprimer plus d'onglets, je pourrais faire quelque chose comme ceci:

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

Où c'est un onglet littéral dans la partie de remplacement sed.

Il peut être plus indépendant du système de parcourir les utilisateurs /etc/passwdet de le faire crontab -l -u $userpour chacun d'eux.

Daniel Papasian
la source
4

Merci pour ce script très utile. J'ai eu de petits problèmes à l'exécuter sur d'anciens systèmes (Red Hat Enterprise 3, qui gèrent différemment egrep et les onglets dans les chaînes), et d'autres systèmes sans rien dans /etc/cron.d/ (le script s'est alors terminé avec une erreur). Voici donc un patch pour le faire fonctionner dans de tels cas:

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

Je ne suis pas vraiment sûr que les changements dans le premier egrep soient une bonne idée, mais bon, ce script a été testé sans problème sur RHEL3,4,5 et Debian5. J'espère que cela t'aides!

jbbarth
la source
3

Construire au sommet de @Kyle

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

pour éviter les commentaires généralement en haut de / etc / passwd,

Et sur macosx

for user in $(dscl . -list /users | cut -f1 -d:); do echo $user; crontab -u $user -l; done    
Ali
la source
3
Ne devriez-vous pas grep -v '^#plutôt que de vous fier au nombre magique 11?
rr
1
Les distributions Red Hat / CentOS n'écrivent pas les conseils utiles au début de la crontab d'un utilisateur, donc couper les 11 premières lignes en effacera le contenu. Même chose si un utilisateur d'Ubuntu a édité sa propre crontab et retiré toute la main.
Dale Anderson
Voir Pourquoi vous ne lisez pas les lignes avec "pour" .
fedorqui 'SO arrêtez de nuire'
3

Je pense qu'une meilleure doublure serait en dessous. Par exemple, si vous avez des utilisateurs dans NIS ou LDAP, ils ne se trouveront pas dans / etc / passwd. Cela vous donnera les crontabs de chaque utilisateur qui s'est connecté.

for I in `lastlog | grep -v Never | cut -f1 -d' '`; do echo $I ; crontab -l -u $I ; done
Monte
la source
Voir Pourquoi vous ne lisez pas les lignes avec "pour" .
fedorqui 'SO arrêtez de nuire'
3

vous pouvez écrire pour toutes les listes d'utilisateurs:

sudo crontab -u userName -l

,

Vous pouvez aussi aller sur

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

ce fichier listera les horaires

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

Toutes mes excuses et merci au yukondude.

J'ai essayé de résumer les paramètres de synchronisation pour une lecture facile, bien que ce ne soit pas un travail parfait, et je ne touche pas `` tous les vendredis '' ou `` uniquement le lundi ''.

Ceci est la version 10 - maintenant:

  • fonctionne beaucoup plus rapidement
  • a des caractères de progression en option afin que vous puissiez améliorer encore la vitesse.
  • utilise une ligne de séparation pour séparer l'en-tête et la sortie.
  • sorties dans un format compact lorsque tous les intervalles de synchronisation rencontrés peuvent être résumés.
  • Accepte les descripteurs Jan ... Dec pour les mois de l'année
  • Accepte les descripteurs Lun ... Sun pour les jours de la semaine
  • essaie de gérer le faux anacron de style Debian quand il est manquant
  • essaie de traiter les lignes crontab qui exécutent un fichier après avoir testé l'exécutabilité en utilisant "[-x ...]"
  • essaie de gérer les lignes crontab qui exécutent un fichier après avoir testé l'exécutabilité en utilisant "command -v"
  • permet l'utilisation de plages d'intervalles et de listes.
  • prend en charge l'utilisation de run-parts dans les fichiers crontab / var / spool spécifiques à l'utilisateur.

Je publie maintenant le script en entier ici.

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

David Collier
la source
2

Puisqu'il s'agit de parcourir un fichier ( /etc/passwd) et d'effectuer une action, je manque l'approche appropriée sur Comment puis-je lire un fichier (flux de données, variable) ligne par ligne (et / ou champ par champ )? :

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

Cela lit /etc/passwdligne par ligne en utilisant :comme délimiteur de champ. En disant read -r user _, on fait $usertenir le premier champ et_ le reste (c'est juste une variable indésirable pour ignorer les champs).

De cette façon, nous pouvons alors appeler en crontab -uutilisant la variable $user, que nous citons pour la sécurité (que faire si elle contient des espaces? C'est peu probable dans un tel fichier, mais vous ne pouvez jamais le savoir).

fedorqui 'SO arrête de nuire'
la source
1

Sous Solaris, pour un nom d'utilisateur connu particulier:

crontab -l username

Tous les autres * Nix auront besoin d'un -umodificateur:

crontab -u username -l

Pour obtenir simultanément tous les travaux des utilisateurs sur Solaris, un peu comme les autres publications ci-dessus:

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

Pour moi, regarder / var / spool / cron / crontabs est la meilleure façon

Nic0
la source
2
cela a déjà été répondu
bummi
-2

Ce script génère la Crontab dans un fichier et répertorie également tous les utilisateurs confirmant ceux qui n'ont pas d'entrée 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
Rob Frost
la source
//, RobFrost, êtes-vous sûr que ce script, tel qu'écrit ici, fonctionne de manière cohérente?
Nathan Basanese
Voir Pourquoi vous ne lisez pas les lignes avec "pour" . En outre, cela a été répondu plusieurs fois avant de poster celui-ci.
fedorqui 'SO arrêtez de nuire'