How do I list all cron jobs for all users?
是否有一个命令或现有脚本可以让我一次查看*nix系统的所有计划cron作业?我希望它包括所有的用户crontabs,以及
理想情况下,我希望输出是一个漂亮的列形式,并以某种有意义的方式进行排序。
然后,我可以从多个服务器合并这些列表,以查看整个"事件日程表"。
我正要自己写这样一个剧本,但如果有人已经惹上麻烦了…
您必须以根用户身份运行它,但是:
1 | for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l; done |
将循环访问列出其crontab的每个用户名。crontab s归各自的用户所有,因此您将无法看到另一个用户的crontab,而不是它们或根用户。
编辑如果您想知道crontab属于哪个用户,请使用
1 | for user in $(cut -f1 -d: /etc/passwd); do echo $user; crontab -u $user -l; done |
我最后写了一个脚本(我试图教自己如何更好地使用bash脚本,所以这里您不会看到Perl这样的东西)。这不是一件简单的事情,但它能满足我的大部分需求。它使用Kyle的建议来查找单个用户的crontabs,还处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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和RedHat AS上测试了它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | #!/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}" |
在Ubuntu或Debian下,可以通过
对于Redhat 6/7和CentOS,crontab在
这将显示所有用户的所有crontab条目。
1 | sed 's/^\([^:]*\):.*$/crontab -u \1 -l 2>\&1/' /etc/passwd | grep -v"no crontab for" | sh |
取决于您的Linux版本,但我使用:
1 | tail -n 1000 /var/spool/cron/* |
作为根。很简单,很短。
给我的输出如下:
1 2 3 4 5 | ==> /var/spool/cron/root <== 15 2 * * * /bla ==> /var/spool/cron/my_user <== */10 1 * * * /path/to/script |
通过改进输出格式对凯尔?伯顿的答案进行了细微的改进:
1 2 3 4 5 | #!/bin/bash for user in $(cut -f1 -d: /etc/passwd) do echo $user && crontab -u $user -l echo"" done |
1 2 3 | getent passwd | cut -d: -f1 | perl -e'while(<>){chomp;$l = `crontab -u $_ -l 2>/dev/null`;print"$_ $l " if $l}' |
这样可以避免直接干扰passwd,跳过没有cron条目的用户,对于那些拥有这些条目的用户,它会打印出用户名和crontab。
不过,我还是把它放在这里,以便以后能找到它,以防我需要再次搜索它。
如果使用nis检查集群,唯一的方法是根据matt的answer/var/spool/cron/tabs查看用户是否有crontab条目列表。
1 | grep -v"#" -R /var/spool/cron/tabs |
这个脚本在CentOS中为我工作,可以列出环境中的所有cron:
1 | sudo cat /etc/passwd | sed 's/^\([^:]*\):.*$/sudo crontab -u \1 -l 2>\&1/' | grep -v"no crontab for" | sh |
我喜欢上面简单的一行回答:
for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l; done
但是Solaris没有-u标志,也没有打印它要检查的用户,您可以这样修改它:
1 | 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)。
1 2 3 4 | for user in $(cut -f1 -d: /etc/passwd); do echo $user; crontab -u $user -l; done |
从根用户获取列表。
1 | for user in $(cut -f1 -d: /etc/passwd); do echo $user; sudo crontab -u $user -l; done |
下面将删除没有crontab的用户的注释、空行和错误。你只剩下一个清晰的用户及其工作列表。
注意在第2行中使用了
1 2 3 4 5 6 7 8 9 | 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 |
实例输出:
1 2 3 4 5 6 7 | # ------ 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)和RedHat(5到7)上使用这个。
取决于cron的版本。在freebsd上使用vixie cron,我可以这样做:
1 | (cd /var/cron/tabs && grep -vH ^# *) |
如果我想要更多的标签被清除,我可以这样做:
1 | (cd /var/cron/tabs && grep -vH ^# * | sed"s/:/ /") |
其中,这是SED替换部分中的文本选项卡。
循环访问
谢谢你的这个非常有用的剧本。我在旧系统上运行它时遇到了一些小问题(Red Hat Enterprise 3,它在字符串中处理不同的出口和标签),以及在/etc/cron.d/中没有任何内容的其他系统上(脚本随后以错误结束)。所以这里有一个补丁可以让它在这种情况下工作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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上进行了测试,没有任何问题。希望这有帮助!
建在@Kyle的顶部
1 | for user in $(tail -n +11 /etc/passwd | cut -f1 -d:); do echo $user; crontab -u $user -l; done |
为了避免评论通常位于/etc/passwd的顶部,
在MaCOSX上
1 | for user in $(dscl . -list /users | cut -f1 -d:); do echo $user; crontab -u $user -l; done |
向育空人致歉并表示感谢。
我试着总结一下阅读的时间设置,虽然这不是一个完美的工作,而且我不会触摸"每周五"或"只在周一"的东西。
这是第10版-现在:
- 跑得快得多
- 具有可选的进度字符,因此可以进一步提高速度。
- 使用分隔线分隔标题和输出。
- 当所有的时间间隔都被计算出来时,可以用紧凑的格式输出。
- 接受一年中几个月的1月至12月描述符
- 接受一周中几天的mon…sun描述符
- 尝试在缺少Anacron时处理Debian样式的虚拟化
- 尝试使用"[-x…"处理在预测试可执行性之后运行文件的crontab行。"
- 尝试使用"command-v"处理在预测试可执行性之后运行文件的crontab行。
- 允许使用间隔跨度和列表。
- 支持在用户特定的/var/spool crontab文件中使用运行部件。
我现在在这里全部出版剧本。
https://gist.github.com/myshkin-uk/d6671116d3e2d689f23f18f6cd3c71107
我想下面会有更好的一条船。例如,如果您在NIS或LDAP中有用户,他们将不会在/etc/passwd中。这将为您提供已登录的每个用户的crontabs。
1 | for I in `lastlog | grep -v Never | cut -f1 -d' '`; do echo $I ; crontab -l -u $I ; done |
您可以为所有用户列表编写:
1 2 3 | sudo crontab -u userName -l , |
你也可以去
1 2 3 | cd /etc/cron.daily/ ls -l cat filename |
此文件将列出计划
1 2 3 | cd /etc/cron.d/ ls -l cat filename |
由于是通过一个文件(
1 2 3 4 5 | while IFS=":" read -r user _ do echo"crontab for user ${user}:" crontab -u"$user" -l done < /etc/passwd |
它使用
这样,我们就可以使用变量
在Solaris上,对于特定的已知用户名:
1 | crontab -l username |
所有其他*nix都需要
1 | crontab -u username -l |
要在Solaris上同时获取所有用户的作业,与上面的其他文章非常相似:
1 | for user in $(cut -f1 -d: /etc/passwd); do crontab -l $user 2>/dev/null; done |
对于我来说,查看/var/spool/cron/crontabs是最好的方法
此脚本将crontab输出到一个文件,并列出所有确认那些没有crontab条目的用户:
1 2 3 4 5 | 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 |