すべてのユーザーのすべてのcronジョブを一覧表示するにはどうすればよいですか?


858

* NIXシステムのスケジュールされたcronジョブのすべてを一度に表示できるコマンドまたは既存のスクリプトはありますか?すべてのユーザーのcrontabや/etc/crontab、およびにあるものをすべて含めたい/etc/cron.dです。またによって実行特定のコマンドを見ていいだろうrun-partsでは/etc/crontab

理想的には、出力を適切な列形式で、意味のある方法で並べたいと思います。

次に、複数のサーバーからのこれらのリストをマージして、全体的な「イベントのスケジュール」を表示できます。

私はそのようなスクリプトを自分で書こうとしていましたが、誰かがすでに問題を抱えている場合は...


2
UnixのSEに同様の質問:unix.stackexchange.com/questions/7053/...
maxschlepzig

回答:


1135

これをrootとして実行する必要がありますが、次のようになります。

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

crontabを一覧表示する各ユーザー名をループします。crontabはそれぞれのユーザーが所有しているため、他のユーザーのcrontabが自分やrootでない場合は表示されません。


crontabがどのユーザーに属しているかを知りたい場合は編集してください。echo $user

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

54
ユーザーがNISまたはLDAPで定義されている場合は機能しません。使用する必要がありますfor user in $(getent passwd | cut -f1 -d: ); do echo $user; crontab -u $user -l; done
Hubert Kario 2012年

10
これはコメントや抑制除外するために「ユーザーのための無crontabファイルを...」のメッセージを更新しました:for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l 2>/dev/null | grep -v '^#'; done
ジョナサン・

38
/ var / spool / cron内のファイルを見る方が簡単ではないでしょうか?
graywh 2013

2
私たちは私たちLDAPと/ etc / passwdのニーズがにgetentコマンドで置き換えられる:for user in $(getent passwd | awk -F : '{print $1}'); do echo $user; crontab -u $user -l; done
トビーバッチ

9
何でcronジョブについて/etc/cron.hourly//etc/cron.daily//etc/cron.weekly//etc/cron.monthly/...?
Abdull、2015年

309

結局、スクリプトを書いてしまいました(bashスクリプトの細かい点を自分に教えようとしているので、Perlのようなものがここに表示されないのはそのためです)。単純なことではありませんが、私が必要とするほとんどのことを行います。これは、個々のユーザーのcrontabファイルを検索するためのカイルの提案を使用しますが、も扱っ/etc/crontab(によって起動スクリプトなどrun-partsでは/etc/cron.hourly/etc/cron.dailyとの仕事、など)/etc/cron.dのディレクトリ。これらすべてを受け取り、次のような表示にマージします。

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

これはユーザーを表示していることに注意してください。日別のスケジュールを確認できるように、時間ごとに並べ替えています。

これまでのところ、Ubuntu、Debian、および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
何もしませんでしたが、/ etc / crontabと/etc/cron.d/のシステムcronジョブについては何もしませんでした。それらを処理し、最後にすべてをフォーマットすることが、私のスクリプトが行うことです。
yukondude 2008

10
yukondude-要点としても、これをgithubに置くことを検討する必要があります。
カイルバートン

3
コピーして貼り付けて実行しようとしましたが、失敗しました:showcrons.sh:59行目:予期しないトークンの近くで構文エラーが発生しました<' showcrons.sh: line 59: <<(cut --fields = 1 --delimiter =:/ etc / passwd) '
Fraggle

2
@KyleBurtonすでにこれをコピーしている少なくとも8つの要点があるようです、gist.github.com
gists /

9
警告:このスクリプトにはイベントがありません/etc/anacrontab
ck_ 2013

191

Ubuntuまたはdebianでは、crontabを表示でき/var/spool/cron/crontabs/、そこに各ユーザーのファイルがあります。もちろん、これはユーザー固有のcrontab専用です。

Redhat 6/7およびCentosの場合、crontabはにあり/var/spool/cron/ます。


7
これはRedHat(/ var / spool / cron)でも機能し、特にLdapなどを使用してアカウントを管理している場合は、スクリプトを作成して実行するよりも簡単です。+1
user49913 2009年

6
これは、他のどの回答よりもはるかに役に立ちました。この方法を使用すると、存在しなくなったユーザーのcrontabを表示して、OPから要求されたすべてのcronジョブを取得できます。
Andrew Ensley、2011

1
この方法のもう1つの利点は、私のサーバーがLDAPを使用しているため、ほとんどのユーザーがにいないことです/etc/passwd。IMOこれは、すべてのブルートフォースソリューションではなく、受け入れられる答えになるはずです。
ミッケル2015

1
ここでSuse Linuxに適しています。
2016

これはAWS EC2インスタンスにも当てはまります。この情報は非常に役に立ちました。
Ivan Marjanovic

34

これにより、すべてのユーザーのすべてのcrontabエントリが表示されます。

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

30

あなたのLinuxバージョンに依存しますが、私は使用します:

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

ルートとして。とてもシンプルでとても短い。

次のような出力が得られます:

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

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

4
tail -n +1 /var/spool/cron/*ファイルのすべてのコンテンツをリストするために使用します。
Hans Ginzel、2015年

4
...またはsudo sh -c 'tail -n +1 /var/spool/cron/*'ルートになりたくない場合。私のOCDは、私がこのコマンドを書いたとおりにsudoできない理由を調査せざるを得ませんでした。これは、通常のユーザーが/ var / spool / cron dirにアクセスできず、グロブが明らかに存在しないリテラルスター文字として解釈されていたためです。
デールアンダーソン

または、cd /var/spool/cron/cron/ && grep . *すべてのcronジョブの前に対応するユーザー名も出力します
Jakub Kukul 2018


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

これは直接passwdをいじるのを避け、cronエントリを持たないユーザーをスキップし、それらを持っているユーザーはユーザー名とcrontabを出力します。

ほとんどここにこれをドロップするので、もう一度検索する必要がある場合に備えて、後で見つけることができます。


1
また、には存在しないLDAPユーザーもリストされます/etc/passwd。上記のマットの解決策は、この特定の状況により適していますが、コマンドが存在することを知っておくとよいでしょう。
ミッケル、2015

11

NISを使用してクラスターをチェックする場合、Mattの回答/ var / spool / cron / tabsに従って、ユーザーがcrontabエントリーを持っているかどうかを確認する唯一の方法です。

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


10

このスクリプトは、CentOSで私のために機能し、環境内のすべてのcronをリストします。

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

2
驚くばかり!私はcronジョブがどのユーザーの下にあるかを確認し、結果の間にスペースを入れるために少しバリエーションを追加しました:cat /etc/passwd | sed 's/^\([^:]*\):.*$/echo "\ncrontab for \1:"; sudo crontab -u \1 -l 2>\&1/' | grep -v "no crontab for" | sh少し時間を節約します
jamil

9

上記の簡単なワンライナーの答えが好きです:

$(cut -f1 -d:/ etc / passwd);のユーザーの場合 crontab -u $ user -lを実行します。できた

しかし、-uフラグがなく、チェックしているユーザーを表示しないSolarisでは、次のように変更できます。

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

アカウントがcronなどの使用を許可されていない場合は、crontabによってスローされたエラーのないユーザーのリストが表示されます。Solarisでは、役割が/ etc / passwdにもあることに注意してください(/ etc / user_attrを参照)。



涼しい。使用しないTIL。
2017年


7

以下は、crontabを使用していないユーザーからのコメント、空行、およびエラーを削除します。残っているのは、ユーザーとそのジョブの明確なリストだけです。

sudo2行目での使用に注意してください。すでにrootになっている場合は、削除してください。

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

出力例:

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

私はこれをUbuntu(12〜16)とRed Hat(5〜7)で使用しています。


5

cronのバージョンによって異なります。FreeBSDでVixie cronを使用すると、次のようなことができます。

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

タブ区切りをもっとしたい場合は、次のようにします。

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

sed置換部分のリテラルタブです。

ユーザーをループしてユーザーごとに/etc/passwd実行する方がシステムに依存しないcrontab -l -u $user場合があります。


4

この非常に便利なスクリプトをありがとう。古いシステム(文字列内のegrepとタブを異なる方法で処理するRed Hat Enterprise 3)、および/etc/cron.d/に何もない他のシステム(スクリプトはエラーで終了しました)で実行すると、小さな問題が発生しました。そのため、このような場合に機能させるためのパッチを次に示します。

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

最初のegrepの変更が良い考えかどうかはよくわかりませんが、まあ、このスクリプトはRHEL3、4、5およびDebian5で問題なくテストされています。お役に立てれば!


3

@Kyleの上に構築する

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

通常/ etc / passwdの上部にあるコメントを避けるために、

そしてmacosx上で

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

3
あなたいけないgrep -v '^#'の代わりにマジックナンバーに頼るの11
rr- 2014

1
Red Hat / CentOSディストリビューションは、ユーザーのcrontabの最初に役立つヒントを書き込まないため、最初の11行を切り捨てると、その内容が消去されます。Ubuntuユーザーが自分のcrontabを編集してすべての手持ちを削除した場合も同様です。
デールアンダーソン


3

より良いワンライナーは下にあると思います。たとえば、NISまたはLDAPにユーザーがいる場合、それらは/ etc / passwdにはありません。これにより、ログインしたすべてのユーザーのcrontabが表示されます。

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


3

あなたはすべてのユーザーリストに書き込むことができます:

sudo crontab -u userName -l

,

あなたも行くことができます

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

このファイルはスケジュールをリストします

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

3

謝罪とyukondudeに感謝します。

私は読みやすいようにタイミング設定をまとめようとしましたが、それは完璧な仕事ではありません。「毎週金曜日」や「月曜日のみ」のものには触れません。

これはバージョン10です-今:

  • ずっと速く走る
  • オプションの進行文字があるので、速度をさらに向上させることができます。
  • ヘッダーと出力を分離するために分割線を使用します。
  • 遭遇したすべてのタイミング間隔を要約できる場合、コンパクトな形式で出力します。
  • Jan ... Dec記述子を数か月間受け入れます
  • 曜日のMon ... Sun記述子を受け入れます
  • アナクロンが欠落している場合、anacronのdebianスタイルのダミー化を処理しようとします
  • 「[-x ...]」を使用して実行可能性を事前テストした後にファイルを実行するcrontab行を処理しようとします
  • 「コマンド-v」を使用して実行可能性を事前テストした後にファイルを実行するcrontab行を処理しようとします
  • 間隔スパンとリストの使用を許可します。
  • ユーザー固有の/ var / spool crontabファイルでのrun-partsの使用をサポートします。

現在、ここでスクリプトを完全に公開しています。

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


2

ファイル(/etc/passwd)をループしてアクションを実行するだけので、ファイル(データストリーム、変数)を行ごと(またはフィールドごと)に読み取るには、適切なアプローチがありません。)?

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

これは、フィールド区切り文字として1 /etc/passwd行ずつ読み取ります:。ということで、最初のフィールドと残りのフィールドread -r user _$user保持します_(フィールドを無視するのは単なるジャンク変数です)。

このようにして、安全のために引用crontab -uした変数を使用して呼び出すことができます$user(スペースが含まれている場合はどうでしょうか?このようなファイルではありそうもありませんが、決して知ることはできません)。


1

Solarisでは、特定の既知のユーザー名の場合:

crontab -l username

他のすべての* Nixには-u修飾子が必要です。

crontab -u username -l

上記の他の投稿と同様に、Solarisですべてのユーザーのジョブを一度に取得するには:

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

-1

私にとって/ var / spool / cron / crontabsを見るのが最善の方法です


2
これは以前に回答されています
bummi

-2

このスクリプトは、Crontabをファイルに出力し、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、このスクリプトは、ここに書かれているように、一貫して機能していますか?
Nathan Basanese

「for」で行を読み取らない理由をご覧ください。また、これを投稿する前に何度も回答されています。
fedorqui 'SO stop harming'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.