Programing

모든 사용자의 모든 크론 작업을 어떻게 나열합니까?

lottogame 2020. 9. 29. 07:10
반응형

모든 사용자의 모든 크론 작업을 어떻게 나열합니까?


* NIX 시스템의 예약 된 cron 작업을 한 번에 모두 볼 수있는 명령이나 기존 스크립트가 있습니까? 나는뿐만 아니라, 그것은 사용자의 크론 탭을 모두 포함하려면 /etc/crontab, 그리고 무엇에 있어요 /etc/cron.d. run-parts에서 실행되는 특정 명령을 보는 것도 좋을 것 입니다 /etc/crontab.

이상적으로는 멋진 열 형식의 출력을 원하고 의미있는 방식으로 정렬하고 싶습니다.

그런 다음 여러 서버에서 이러한 목록을 병합하여 전체 "이벤트 일정"을 볼 수 있습니다.

그런 대본을 직접 쓰려고했는데 이미 누군가가 문제가 생긴다면 ...


이것을 루트로 실행해야하지만 :

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

crontab을 나열하는 각 사용자 이름을 반복합니다. crontab은 각 사용자가 소유하므로 다른 사용자의 crontab이 자신이나 루트가 아니더라도 볼 수 없습니다.


crontab이 속한 사용자를 알고 싶다면 편집하십시오.echo $user

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

나는 결국 스크립트를 작성하게되었다. (나는 bash 스크립팅의 더 세밀한 요점을 스스로 가르치려고 노력하고있다. 그래서 여기서 Perl과 같은 것을 보지 못하는 것이다). 그것은 정확히 단순한 일은 아니지만 내가 필요한 대부분을 수행합니다. 그것은 개별 사용자의 크론 탭을 찾기위한 카일의 제안을 사용하지만, 또한 취급 /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}"

Ubuntu 또는 debian에서 crontab을 볼 수 있으며 /var/spool/cron/crontabs/각 사용자에 대한 파일이 거기에 있습니다. 물론 사용자 별 crontab에만 해당됩니다.

Redhat 6/7 및 Centos의 경우 crontab은 /var/spool/cron/.


모든 사용자의 모든 crontab 항목이 표시됩니다.

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

Linux 버전에 따라 다르지만 다음을 사용합니다.

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

루트로. 매우 간단하고 매우 짧습니다.

다음과 같은 출력을 제공합니다.

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

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

향상된 출력 형식으로 Kyle Burton의 답변을 약간 수정했습니다.

#!/bin/bash
for user in $(cut -f1 -d: /etc/passwd)
do echo $user && crontab -u $user -l
echo " "
done

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을 출력합니다.

Mostly dropping this here though so i can find it later in case i ever need to search for it again.


If you check a cluster using NIS, the only way to see if a user has a crontab entry ist according to Matt's answer /var/spool/cron/tabs.

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

This script worked for me in CentOS to list all crons in the environment:

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

I like the simple one-liner answer above:

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

But Solaris which does not have the -u flag and does not print the user it's checking, you can modify it like so:

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

You will get a list of users without the errors thrown by crontab when an account is not allowed to use cron etc. Be aware that in Solaris, roles can be in /etc/passwd too (see /etc/user_attr).


To get list from ROOT user.

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

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

The following strips away comments, empty lines, and errors from users with no crontab. All you're left with is a clear list of users and their jobs.

Note the use of sudo in the 2nd line. If you're already root, remove that.

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

Example output:

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

I use this on Ubuntu (12 thru 16) and Red Hat (5 thru 7).


Depends on your version of cron. Using Vixie cron on FreeBSD, I can do something like this:

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

if I want it more tab deliminated, I might do something like this:

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

Where that's a literal tab in the sed replacement portion.

It may be more system independent to loop through the users in /etc/passwd and do crontab -l -u $user for each of them.


Thanks for this very useful script. I had some tiny problems running it on old systems (Red Hat Enterprise 3, which handle differently egrep and tabs in strings), and other systems with nothing in /etc/cron.d/ (the script then ended with an error). So here is a patch to make it work in such cases :

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

I'm not really sure the changes in the first egrep are a good idea, but well, this script has been tested on RHEL3,4,5 and Debian5 without any problem. Hope this helps!


Building on top of @Kyle

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

to avoid the comments usually at the top of /etc/passwd,

And on macosx

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

I think a better one liner would be below. For example if you have users in NIS or LDAP they wouldnt be in /etc/passwd. This will give you the crontabs of every user that has logged in.

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

you can write for all user list :

sudo crontab -u userName -l

,

You can also go to

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

this file will list the schedules

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

With apologies and thanks to yukondude.

I've tried to summarise the timing settings for easy reading, though it's not a perfect job, and I don't touch 'every Friday' or 'only on Mondays' stuff.

This is version 10 - it now:

  • runs much much faster
  • has optional progress characters so you could improve the speed further.
  • uses a divider line to separate header and output.
  • outputs in a compact format when all timing intervals uencountered can be summarised.
  • Accepts Jan...Dec descriptors for months-of-the-year
  • Accepts Mon...Sun descriptors for days-of-the-week
  • tries to handle debian-style dummying-up of anacron when it is missing
  • tries to deal with crontab lines which run a file after pre-testing executability using "[ -x ... ]"
  • tries to deal with crontab lines which run a file after pre-testing executability using "command -v"
  • allows the use of interval spans and lists.
  • supports run-parts usage in user-specific /var/spool crontab files.

I am now publishing the script in full here.

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


Since it is a matter of looping through a file (/etc/passwd) and performing an action, I am missing the proper approach on 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

This reads /etc/passwd line by line using : as field delimiter. By saying read -r user _, we make $user hold the first field and _ the rest (it is just a junk variable to ignore fields).

This way, we can then call crontab -u using the variable $user, which we quote for safety (what if it contains spaces? It is unlikely in such file, but you can never know).


On Solaris, for a particular known user name:

crontab -l username

All other *Nix will need -u modifier:

crontab -u username -l

To get all user's jobs at once on Solaris, much like other posts above:

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

For me look at /var/spool/cron/crontabs is the best way


This script outputs the Crontab to a file and also lists all users confirming those which have no crontab entry:

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

참고URL : https://stackoverflow.com/questions/134906/how-do-i-list-all-cron-jobs-for-all-users

반응형