Pergunta

Existe um comando ou um script existente que me permite ver todas as tarefas agendadas agendadas de um sistema * NIX de uma vez? Eu gostaria que incluem todos os crontabs usuário, bem como /etc/crontab, e tudo o que está em /etc/cron.d. Também seria bom ver os comandos específicos executados por run-parts em /etc/crontab.

Idealmente, eu gostaria que a saída em uma forma de coluna agradável e ordenada, de alguma forma significativa.

Eu poderia, então, mesclar essas imóveis de vários servidores para ver o geral "calendário de eventos".

Eu estava prestes a escrever um script de mim mesmo, mas se alguém já foi para o problema ...

Foi útil?

Solução 2

Acabei escrevendo um script (que estou tentando ensinar-me os melhores pontos de scripting bash, é por isso que você não vê algo como Perl aqui). Não é exatamente um caso simples, mas faz mais do que eu preciso. Ele usa a sugestão de Kyle para procurar crontabs de usuários individuais, mas também lida com /etc/crontab (incluindo os scripts lançados pela run-parts em /etc/cron.hourly, /etc/cron.daily, etc.) e os postos de trabalho no diretório /etc/cron.d. Leva todos aqueles e funde-os em um algo parecido com o seguinte:

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

Note que mostra ao usuário, e mais ou menos os tipos de hora e minuto para que eu possa ver a programação diária.

Até agora, eu testei no Ubuntu, Debian e 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}"

Outras dicas

Você teria que executar este como root, mas:

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

circuito vontade sobre cada nome de usuário listando sua crontab. Os crontabs são de propriedade dos respectivos usuários para que você não será capaz de ver crontab de outro usuário w / o sendo eles ou raiz.


Editar se você quiser saber qual usuário uma crontab pertence, uso echo $user

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

De acordo com o Ubuntu ou Debian, você pode ver crontab por /var/spool/cron/crontabs/ e, em seguida, um arquivo para cada usuário está lá. Isso é apenas para crontab específicas do usuário de é claro.

Para Redhat 6/7 e Centos, o crontab está sob /var/spool/cron/.

Isto irá mostrar todas as entradas crontab de todos os usuários.

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

Depende de sua versão Linux, mas eu uso:

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

como root. Muito simples e muito curto.

Dá-me uma saída como:

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

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

Uma pequena refinamento da resposta de Kyle Burton com uma melhor saída de formatação:

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

Isso evita brincando com passwd diretamente, salta aos usuários que não têm entradas cron e para aqueles que os têm que imprime o nome de usuário, bem como a sua crontab.

Na maior parte largando isso aqui embora para que eu possa encontrá-lo mais tarde no caso de eu precisar procurá-lo novamente.

Se você verificar um cluster usando NIS, a única maneira de ver se o usuário tem uma ist entrada crontab de acordo com a resposta de Matt / var / spool / cron / tabs.

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

Este script funcionou para mim no CentOS para listar todos crons no ambiente:

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

Eu gosto da simples resposta de uma linha acima:

para o utilizador em $ (corte -f1 -d: / etc / passwd); fazer crontab -u -l $ user; done

Mas Solaris que não tem a bandeira -u e não imprime o usuário que está verificando, você pode modificá-lo assim:

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

Você receberá uma lista de usuários sem os erros lançados por crontab quando uma conta não está autorizada a usar o cron etc Esteja ciente de que, em Solaris, papéis pode estar em / etc / passwd também (veja / etc / user_attr).

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

Para obter a lista de usuário root.

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

A seguir desnuda comentários, linhas vazias e erros dos usuários sem crontab. Tudo o que você é deixado com uma lista clara de usuários e seus empregos.

Observe o uso de sudo na 2ª linha. Se você já é root, remova isso.

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

Exemplo de saída:

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

Eu uso isso no Ubuntu (12-16) e Red Hat (5-7).

Depende da sua versão do cron. Usando Vixie cron no FreeBSD, eu posso fazer algo como isto:

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

se eu quero mais guia deliminated, eu poderia fazer algo parecido com isto:

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

Onde isso é um guia literal na parte de substituição sed.

Pode ser mais independente do sistema para percorrer os usuários em /etc/passwd e fazer crontab -l -u $user para cada um deles.

Obrigado por este script muito útil. Eu tive alguns pequenos problemas executando-o em sistemas antigos (Red Hat Enterprise 3, que lidam de forma diferente egrep e abas em cordas) e outros sistemas com nada em /etc/cron.d/ (o script, em seguida, terminou com um erro). Então aqui é um patch para que ele funcione em tais casos:

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

Eu não estou realmente certo as mudanças no primeiro egrep são uma boa idéia, mas bem, esse script foi testado em RHEL3,4,5 e Debian5 sem qualquer problema. Espero que isso ajude!

Com base no topo da @Kyle

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

para evitar geralmente os comentários no topo do / etc / passwd,

E em MacOSX

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

Eu acho que um melhor forro seria abaixo. Por exemplo, se você tiver usuários em NIS ou LDAP que não estaria em / etc / passwd. Isto lhe dará os crontabs de cada usuário que tenha logado.

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

você pode escrever para toda a lista de usuário:

sudo crontab -u userName -l

,

Você também pode ir para

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

Este arquivo irá listar os horários

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

Com desculpas e graças a yukondude.

Eu tentei resumir as configurações de tempo para a leitura fácil, embora não seja um trabalho perfeito, e eu não toque 'toda sexta-feira' ou 'apenas às segundas-feiras' coisas.

Esta é a versão 10 - agora:

  • corre muito mais rápida
  • tem caracteres progresso opcionais para que você possa melhorar ainda mais a velocidade.
  • usa uma linha divisória para cabeçalho e saída separada.
  • saídas em um formato compacto quando todos os intervalos de tempo uencountered pode ser resumido.
  • Aceita Jan ... descritores Dez por meses-of-the-year
  • Aceita Mon ... descritores Sun por dias-of-the-semana
  • tenta pega-style debian dummying-up de anacron quando ele estiver ausente
  • tenta lidar com linhas crontab que executar um arquivo após a pré-testar exequibilidade usando "[-x ...]"
  • tenta lidar com linhas crontab que executar um arquivo após a pré-testar exequibilidade utilizando "comando -v"
  • permite o uso de extensões de intervalo e listas.
  • suportes de gerência peças uso em específico do usuário / var / spool crontab arquivos.

Agora estou publicando o roteiro na íntegra aqui.

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

Uma vez que é uma questão de looping através de um arquivo (/etc/passwd) e realizando uma ação, eu estou faltando a abordagem adequada em Como posso ler um arquivo (fluxo de dados, variável), linha por linha (e / ou campo-a-campo) :?

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

Este lê linha /etc/passwd por linha utilizando : como delimitador de campo. Ao dizer read -r user _, fazemos $user espera o primeiro campo e _ o resto (que é apenas uma variável junk ignorar campos).

Desta forma, podemos chamar crontab -u usando o $user variável, que citamos para a segurança (o que se contém espaços? É improvável em tal arquivo, mas você nunca pode saber).

No Solaris, um nome de usuário conhecido nomeadamente:

crontab -l username

Todas as outras * Nix terá modificador -u:

crontab -u username -l

Para obter empregos de todo o usuário de uma só vez no Solaris, bem como outras mensagens anteriores:

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

Para mim olhar para / var / spool / cron / crontabs é a melhor maneira

Este script gera o Crontab para um arquivo e também lista todos os usuários confirmando aqueles que não têm entrada 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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top