首页 文章

如何列出所有用户的所有cron作业?

提问于
浏览
757

是否有命令或现有脚本可以让我查看所有* NIX系统's scheduled cron jobs at once? I' d,它包括所有用户crontabs,以及 /etc/crontab ,以及 /etc/cron.d 中的任何内容 . 在 /etc/crontab 中查看由 run-parts 运行的特定命令也会很高兴 .

理想情况下,我希望输出采用漂亮的列形式,并以一些有意义的方式进行排序 .

然后,我可以合并来自多个服务器的这些列表,以查看整个“事件安排” .

我本来就要写这样一个剧本,但如果有人已经麻烦了......

22 回答

  • 2

    以下删除了没有crontab的用户的注释,空行和错误 . 您剩下的就是清晰的用户及其工作清单 .

    注意在第二行使用 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)上使用它 .

  • 14

    你必须以root身份运行它,但是:

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

    将循环遍历其crontab的每个用户名 . crontabs由各自的用户拥有,因此您将无法看到另一个用户的crontab,而不是他们或root用户 .


    Edit 如果您想知道crontab属于哪个用户,请使用 echo $user

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

    我最后写了一个脚本(我为什么你不是一个简单的事情,但它完成了我需要的大部分工作 . 它使用Kyle 's suggestion for looking up individual users' crontabs,但也处理 /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}"
    
  • -2

    在Ubuntu或debian下,您可以通过 /var/spool/cron/crontabs/ 查看crontab,然后每个用户的文件都在那里 . 那个's only for user-specific crontab'当然 .

  • 2

    这将显示所有用户的所有crontab条目 .

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

    取决于你的Linux版本,但我使用:

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

    作为根 . 非常简单而且很短 .

    给我输出像:

    ==> /var/spool/cron/root <==
    15 2 * * * /bla
    
    ==> /var/spool/cron/my_user <==
    */10 1 * * * /path/to/script
    
  • 1

    Kyle Burton对改进输出格式的一个小改进:

    #!/bin/bash
    for user in $(cut -f1 -d: /etc/passwd)
    do echo $user && crontab -u $user -l
    echo " "
    done
    
  • 1018
    getent passwd | cut -d: -f1 | perl -e'while(<>){chomp;$l = `crontab -u $_ -l 2>/dev/null`;print "$_\n$l\n" if $l}'
    

    这样可以避免直接搞乱passwd,跳过没有cron条目的用户,对于那些拥有cron条目的用户,它会打印出用户名以及crontab .

    大部分都放在这里虽然所以我以后可以找到它以防万一我需要再次搜索它 .

  • 5

    如果使用NIS检查集群,则根据Matt的答案/ var / spool / cron / tabs查看用户是否具有crontab条目的唯一方法 .

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

    我喜欢上面简单的单行答案:

    对于$中的用户(cut -f1 -d:/ etc / passwd); do crontab -u $ user -l; DONE

    但是Solaris没有-u标志并且不打印它正在检查的用户,你可以像这样修改它:

    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) .

  • 4

    这个脚本在CentOS中为我工作,列出了环境中的所有crons:

    sudo cat /etc/passwd | sed 's/^\([^:]*\):.*$/sudo crontab -u \1 -l 2>\&1/' | grep -v "no crontab for" | sh
    
  • 293
    for user in $(cut -f1 -d: /etc/passwd); 
    do 
        echo $user; crontab -u $user -l; 
    done
    
  • 1

    取决于您的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 .

  • 156

    感谢这个非常有用的脚本 . 我在旧系统上运行它有一些小问题(Red Hat Enterprise 3,它处理不同的egrep和字符串中的选项卡),以及/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上进行了测试,没有任何问题 . 希望这可以帮助!

  • 2

    Build 在@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
    
  • 8

    我认为更好的一个班轮将在下面 . 例如,如果您有NIS或LDAP中的用户,则他们不会在/ etc / passwd中 . 这将为您提供已登录的每个用户的crontabs .

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

    你可以为所有用户列表写:

    sudo crontab -u userName -l
    
    ,
    

    你也可以去

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

    此文件将列出计划

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

    从ROOT用户获取列表 .

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

    由于这是循环文件( /etc/passwd )并执行操作的问题,我在How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?上错过了正确的方法:

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

    这使用 : 作为字段分隔符逐行读取 /etc/passwd . 通过说 read -r user _ ,我们让 $user 持有第一个字段和 _ 其余的(它只是一个忽略字段的垃圾变量) .

    这样,我们就可以使用变量 $user 来调用 crontab -u ,我们引用它是为了安全(如果它包含空格怎么办?在这样的文件中不太可能,但你永远不会知道) .

  • 7

    在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
    
  • 8

    对我来说,看看/ var / spool / cron / crontabs是最好的方法

  • 10

    此脚本将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
    

相关问题