web-dev-qa-db-ja.com

すべてのユーザーのすべてのcronジョブを一覧表示する方法

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

理想的には、出力をNice列形式で表示し、意味のある順序で並べてください。

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

私は自分自身でそのようなスクリプトを書くことにしていました、しかし誰かがすでに問題に行ったならば...

786
yukondude

私は最終的にスクリプトを書くことになりました(bashスクリプトのより細かい点を自分自身に教えようとしているので、ここにPerlのようなものが見えないのです)。それは正確に単純なことではありませんが、私が必要とするもののほとんどを行います。個々のユーザーのcrontabを検索するためにKyleの提案を使用しますが、/etc/crontabrun-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}"
301
yukondude

これを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
1064
Kyle Burton

Ubuntuやdebianの下では、crontabを/var/spool/cron/crontabs/で見ることができ、そこに各ユーザーのファイルがあります。それはもちろんユーザー固有のcrontabのためだけです。

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

171
Matt

これはすべてのユーザーからのすべてのcrontabエントリを表示します。

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

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

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

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

私に出力を与えます:

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

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

Kyle Burtonの答えを少し改良した、出力フォーマットの改善:

#!/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}'

これはpasswdを直接めちゃくちゃにすることを避け、cronエントリーを持たないユーザーをスキップし、それらを持っているユーザーのためにユーザー名とcrontabをプリントアウトします。

ただし、ここでこれをドロップすると、後で検索する必要が生じた場合に備えて後で見つけることができます。

13
Mithaldu

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

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

このスクリプトはCentOSで私の環境内のすべてのクローンを一覧表示するのに役立ちました。

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

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

$のユーザー用(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参照)。

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

以下は、crontabがないユーザーからのコメント、空行、およびエラーを削除したものです。残っているのは、ユーザーとその仕事の明確なリストだけです。

2行目のSudoの使用に注意してください。すでに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
Dale Anderson

ROOTユーザーからリストを取得します。

for user in $(cut -f1 -d: /etc/passwd); do echo $user; Sudo crontab -u $user -l; done
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
Daniel Papasian

この非常に便利なスクリプトをありがとう。古いシステム(文字列内の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
jbbarth

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

Sudo crontab -u userName -l

,

またに行くことができます

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

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

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

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

謝罪と、yukondudeに感謝します。

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

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

  • ずっと速く走る
  • あなたはさらにスピードを向上させることができるようにオプションのプログレス文字を持っています。
  • ヘッダーと出力を分離するために分割線を使用します。
  • 遭遇しないすべてのタイミング間隔が要約されることができるとき、コンパクトなフォーマットで出力します。
  • Jan-Dec-of-yearのJan ... Dec記述子を受け入れます
  • 曜日の月〜日の記述子を受け入れます
  • anacronが見つからないときにdebianスタイルのダミーアップを処理しようとします。
  • "[-x ...]"を使用して実行可能性を事前テストした後にファイルを実行するcrontab行を処理しようとします
  • "command -v"を使用して実行可能性を事前テストした後にファイルを実行するcrontab行を処理しようとします
  • インターバルスパンおよびリストの使用を許可します。
  • ユーザー固有の/ var/spool crontabファイルでの実行部分の使用をサポートします。

私は今ここでスクリプトを完全に公開しています。

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

2
david collier

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

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

ファイル(/etc/passwd)をループ処理してアクションを実行することが問題であるため、 ファイル(データストリーム、変数)を1行ずつ(および/またはフィールドで)読み取る方法はありません。フィールド)

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

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

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

1
fedorqui

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
armagedescu