Teste um trabalho cron semanal [fechado]


237

Eu tenho um #!/bin/basharquivo no diretório cron.week.

Existe uma maneira de testar se funciona? Mal posso esperar 1 semana

Estou no Debian 6 com root


4
Você não pode simplesmente testar o script executando-o na linha de comando?
Frédéric Hamidi

5
basta adicionar uma entrada separada na sua crontabque executa seu arquivo a cada poucos minutos, ver se os resultados esperados estão lá e excluir a entrada de teste do seu crontab. tentecrontab -e
davin

61
Não, executá-lo na linha de comando não é uma boa maneira. Apenas executar o script a partir da linha de comando não garante que ele seja executado como o mesmo usuário que executou no cron. Mesmo que seja executado como o mesmo usuário, você nunca poderá ter certeza se tudo o resto será o mesmo. Os scripts que funcionam na linha de comando podem falhar por todos os tipos de razões quando executados no cron.
andynormancx

8
"todos os tipos" pode ser sido um pouco hiperbólico ... permissões e variáveis de ambiente são os dois que vêm à mente, você poderia facilmente ter diferentes outras condições iniciais como aliases embora
andynormancx

3
Acabei de testar um novo trabalho cron, adicionarei outro item a "todos os tipos". Se você possui itens no bash_profile, eles não são executados uma vez em um trabalho cron, enquanto o teste do trabalho na linha de comando funciona perfeitamente. Testar tarefas cron na linha de comando padrão não é um bom teste.
precisa saber é o seguinte

Respostas:


233

Basta fazer o que o cron faz, execute o seguinte como root:

run-parts -v /etc/cron.weekly

... ou o próximo se você receber o erro "Não é um diretório: -v":

run-parts /etc/cron.weekly -v

A opção -vimprime os nomes dos scripts antes de serem executados.


4
Se eu usar a opção -v mostrando o erro "Não é um diretório: -v", não há página de manual para este comando no meu sistema, -v significa detalhado, certo? Estou usando centos 6.4
max

3
Para evitar o erro "Não é um diretório", eu tinha que fazer isso em vez disso: run-parts /etc/cron.weekly -v
Craig Hyatt

22
Mas isso não leva em consideração as variáveis de ambiente que poderiam ser definidas no crontab
fcurella

34
run-partsapenas executa os scripts de um determinado diretório. Nada a ver com cron.
Nicolas

23
Isso realmente não deveria ter sido votado e aceito, além de executar o script, não faz nada para dizer se o script realmente funcionará quando executado a partir do cron. Use o excelente script de crontest em uma das outras respostas a esta pergunta.
precisa saber é o seguinte

87

Um pouquinho além do escopo da sua pergunta ... mas aqui está o que eu faço.

O "como faço para testar um trabalho cron?" A questão está intimamente ligada a "como testar scripts executados em contextos não interativos iniciados por outros programas?" No cron, o gatilho é uma condição de tempo, mas muitas outras instalações * nix iniciam scripts ou fragmentos de scripts de maneiras não interativas, e geralmente as condições nas quais esses scripts são executados contêm algo inesperado e causam falhas até que os erros sejam resolvidos. (Veja também: https://stackoverflow.com/a/17805088/237059 )

É útil ter uma abordagem geral desse problema.

Uma das minhas técnicas favoritas é usar um script que escrevi chamado ' crontest '. Ele lança o comando target dentro de uma sessão de tela GNU de dentro do cron, para que você possa conectar com um terminal separado para ver o que está acontecendo, interagir com o script e até usar um depurador.

Para configurar isso, você deve usar "all stars" na entrada do crontab e especificar crontest como o primeiro comando na linha de comando, por exemplo:

* * * * * crontest /command/to/be/tested --param1 --param2

Portanto, agora o cron executará seu comando a cada minuto, mas o crontest garantirá que apenas uma instância seja executada por vez. Se o comando levar algum tempo para ser executado, você poderá executar uma "tela -x" para anexar e assistir à execução. Se o comando for um script, você poderá colocar um comando "read" na parte superior para parar e aguardar a conclusão do anexo da tela (pressione enter após anexar)

Se seu comando é um script bash, você pode fazer isso:

* * * * * crontest --bashdb /command/to/be/tested --param1 --param2

Agora, se você se conectar com "screen -x", estará enfrentando uma sessão interativa do bashdb e poderá percorrer o código, examinar variáveis ​​etc.

#!/bin/bash

# crontest
# See https://github.com/Stabledog/crontest for canonical source.

# Test wrapper for cron tasks.  The suggested use is:
#
#  1. When adding your cron job, use all 5 stars to make it run every minute
#  2. Wrap the command in crontest
#        
#
#  Example:
#
#  $ crontab -e
#     * * * * * /usr/local/bin/crontest $HOME/bin/my-new-script --myparams
#
#  Now, cron will run your job every minute, but crontest will only allow one
#  instance to run at a time.  
#
#  crontest always wraps the command in "screen -d -m" if possible, so you can
#  use "screen -x" to attach and interact with the job.   
#
#  If --bashdb is used, the command line will be passed to bashdb.  Thus you
#  can attach with "screen -x" and debug the remaining command in context.
#
#  NOTES:
#   - crontest can be used in other contexts, it doesn't have to be a cron job.
#       Any place where commands are invoked without an interactive terminal and
#       may need to be debugged.
#
#   - crontest writes its own stuff to /tmp/crontest.log
#
#   - If GNU screen isn't available, neither is --bashdb
#

crontestLog=/tmp/crontest.log
lockfile=$(if [[ -d /var/lock ]]; then echo /var/lock/crontest.lock; else echo /tmp/crontest.lock; fi )
useBashdb=false
useScreen=$( if which screen &>/dev/null; then echo true; else echo false; fi )
innerArgs="$@"
screenBin=$(which screen 2>/dev/null)

function errExit {
    echo "[-err-] $@" | tee -a $crontestLog >&2
}

function log {
    echo "[-stat-] $@" >> $crontestLog
}

function parseArgs {
    while [[ ! -z $1 ]]; do
        case $1 in
            --bashdb)
                if ! $useScreen; then
                    errExit "--bashdb invalid in crontest because GNU screen not installed"
                fi
                if ! which bashdb &>/dev/null; then
                    errExit "--bashdb invalid in crontest: no bashdb on the PATH"
                fi

                useBashdb=true
                ;;
            --)
                shift
                innerArgs="$@"
                return 0
                ;;
            *)
                innerArgs="$@"
                return 0
                ;;
        esac
        shift
    done
}

if [[ -z  $sourceMe ]]; then
    # Lock the lockfile (no, we do not wish to follow the standard
    # advice of wrapping this in a subshell!)
    exec 9>$lockfile
    flock -n 9 || exit 1

    # Zap any old log data:
    [[ -f $crontestLog ]] && rm -f $crontestLog

    parseArgs "$@"

    log "crontest starting at $(date)"
    log "Raw command line: $@"
    log "Inner args: $@"
    log "screenBin: $screenBin"
    log "useBashdb: $( if $useBashdb; then echo YES; else echo no; fi )"
    log "useScreen: $( if $useScreen; then echo YES; else echo no; fi )"

    # Were building a command line.
    cmdline=""

    # If screen is available, put the task inside a pseudo-terminal
    # owned by screen.  That allows the developer to do a "screen -x" to
    # interact with the running command:
    if $useScreen; then
        cmdline="$screenBin -D -m "
    fi

    # If bashdb is installed and --bashdb is specified on the command line,
    # pass the command to bashdb.  This allows the developer to do a "screen -x" to
    # interactively debug a bash shell script:
    if $useBashdb; then
        cmdline="$cmdline $(which bashdb) "
    fi

    # Finally, append the target command and params:
    cmdline="$cmdline $innerArgs"

    log "cmdline: $cmdline"


    # And run the whole schlock:
    $cmdline 

    res=$?

    log "Command result: $res"


    echo "[-result-] $(if [[ $res -eq 0 ]]; then echo ok; else echo fail; fi)" >> $crontestLog

    # Release the lock:
    9<&-
fi

2
Incrível, a solução perfeita. Todas as outras técnicas que eu tentei realmente não funcionaram, o crontest resolveu o problema facilmente.
precisa saber é o seguinte

1
Isso foi muito mais do que eu precisava, mas +1 para uma ótima solução de qualquer maneira; configurar o cron para ser executado com mais frequência e despejar a saída em / tmp foi bom o suficiente para detectar meu problema.
Jcollum

2
Legal. Sim, não há razão para o fogo até a bulldozer se você só precisa de uma pá mão :)
Stabledog

2
Coisas boas. Nota sobre mac eu tinha que brew tap discoteq/discoteq; brew install flocke modifique o script para usar/usr/local/bin/flock
Claudiu

1
bom utilitário! Muito útil para diagnosticar problemas de autenticação em contextos não interativos.
Eric Blum

44

Depois de mexer com algumas coisas no cron que não eram instantaneamente compatíveis, achei que a seguinte abordagem era boa para depuração:

crontab -e

* * * * * /path/to/prog var1 var2 &>>/tmp/cron_debug_log.log

Isso executará a tarefa uma vez por minuto e você pode simplesmente procurar no /tmp/cron_debug_log.logarquivo para descobrir o que está acontecendo.

Não é exatamente o "trabalho de fogo" que você pode estar procurando, mas isso me ajudou muito ao depurar um script que não funcionou no cron no início.


9
Eu recomendaria essa abordagem. O problema na maioria dos casos é que você não vê o erro.
Yauhen Yakimovich

8
Linha incorreta, nenhuma distribuição usa bash para o cron shell e, portanto, o >> não funciona. Eu sugiro usar >>/tmp/cron_debug_log.log 2>&1vez
drizzt

1
O que você quer dizer com /path/to/prog- qual prog?
Nathan

3
O programa que você irá executar com o cron. Isso pode ser usr/home/myFancyScript.shou pode ser simples ls, ou o que você deseja executar regularmente.
Automatico

Isso funcionou para mim. Foi o método mais fácil de fazer um teste rápido para verificar se está tudo bem
abhijit

25

Eu usaria um arquivo de bloqueio e, em seguida, definiria o trabalho cron para executar a cada minuto. (use crontab -e e * * * * * / path / to / job) Dessa forma, você pode continuar editando os arquivos e a cada minuto eles serão testados. Além disso, você pode interromper o cronjob apenas tocando no arquivo de bloqueio.

    #!/bin/sh
    if [ -e /tmp/cronlock ]
    then
        echo "cronjob locked"
        exit 1
    fi

    touch /tmp/cronlock
    <...do your regular cron here ....>
    rm -f /tmp/cronlock

4
Você também pode usar a flock(1)partir do shell; veja man 1 flock. Bastante útil para esses usos, pois fornece bloqueio automático.
Craig Ringer

5

Que tal colocá-lo em cron.hourly, aguardar até a próxima execução de tarefas cron de hora em hora e removê-lo? Isso o executaria uma vez em uma hora e no ambiente cron. Você também pode executar ./your_script, mas isso não terá o mesmo ambiente que no cron.


este é praticamente o mesmo que @ resposta de Cort3z, com menos detalhe
jcollum

5

Nenhuma dessas respostas se encaixa na minha situação específica: eu queria executar um trabalho cron específico, apenas uma vez e executá-lo imediatamente.

Estou em um servidor Ubuntu e uso o cPanel para configurar meus trabalhos cron.

Simplesmente anotei minhas configurações atuais e as editei daqui a um minuto. Quando consertei outro bug, apenas o editei novamente daqui a um minuto. E quando terminei, redefini as configurações para como estavam antes.

Exemplo: São 16:34 no momento, então eu coloquei 35 16 * * *, para que seja executado às 16:35.

Funcionou como um encanto, e o máximo que eu já tive que esperar foi um pouco menos de um minuto.

Eu pensei que essa era uma opção melhor do que algumas das outras respostas, porque não queria executar todos os meus crons semanais e não queria que o trabalho fosse executado a cada minuto. Demoro alguns minutos para corrigir os problemas antes que eu esteja pronto para testá-lo novamente. Espero que isso ajude alguém.


Por que você usaria o cron para executar "apenas uma vez e executá-lo imediatamente"? Parece que você estaria melhor apenas executando o script diretamente.
Ian Hunter

4

Além disso, você também pode usar:

http://pypi.python.org/pypi/cronwrap

para finalizar seu cron e enviar um email em caso de sucesso ou falha.


10
O Cron já não envia e-mails e resultados do script após a execução?
quer

Enviar emails para o usuário e, normalmente, o usuário para a maioria das tarefas cron é um usuário root ou apenas um serviço não interativo, para que você nunca os veja. É assim que os servidores são preenchidos quando um erro desencadeia uma enorme enxurrada de emails e eles saltam para a raiz.
dragon788

3

A solução que estou usando é a seguinte:

  1. Edite o crontab (use o comando: crontab -e) para executar o trabalho com a frequência necessária (a cada 1 ou 5 minutos)
  2. Modifique o script de shell que deve ser executado usando cron para imprimir a saída em algum arquivo (por exemplo: echo "Working fine" >>
    output.txt)
  3. Verifique o arquivo output.txt usando o comando: tail -f output.txt, que imprimirá as adições mais recentes nesse arquivo e, assim, você poderá acompanhar a execução do script

2

Normalmente eu testo executando o trabalho que criei assim:

É mais fácil usar dois terminais para fazer isso.

executar trabalho:

#./jobname.sh

vamos para:

#/var/log and run 

execute o seguinte:

#tailf /var/log/cron

Isso me permite ver os cron logs atualizados em tempo real. Você também pode revisar o log depois de executá-lo. Prefiro assistir em tempo real.

Aqui está um exemplo de uma tarefa cron simples. Executando uma atualização yum ...

#!/bin/bash
YUM=/usr/bin/yum
$YUM -y -R 120 -d 0 -e 0 update yum
$YUM -y -R 10 -e 0 -d 0 update

Aqui está o detalhamento:

O primeiro comando atualizará o yum e o próximo aplicará as atualizações do sistema.

-R 120: Define a quantidade máxima de tempo que você espera antes de executar um comando

-e 0: define o nível de erro para 0 (intervalo de 0 a 10). 0 significa imprimir apenas erros críticos sobre os quais você deve ser informado.

-d 0: define o nível de depuração para 0 - aumenta ou diminui a quantidade de itens impressos. (intervalo: 0 - 10).

-y: Suponha que sim; suponha que a resposta a qualquer pergunta que seja feita é sim

Depois de criar o trabalho cron, executei o comando abaixo para tornar meu trabalho executável.

#chmod +x /etc/cron.daily/jobname.sh 

Espero que isso ajude, Dorlack


2
sudo run-parts --test /var/spool/cron/crontabs/

arquivos nesse crontabs/diretório precisam ser executáveis ​​pelo proprietário - octal700

fonte: man crone NNRooth's


5
Duas coisas. Primeiro: executar coisas como sudo usa um ambiente diferente (variáveis ​​definidas). Portanto, erros no seu crontab podem funcionar quando executados como 'sudo', mas não funcionam quando executados como 'root' (e vice-versa). Segundo: 'man cron' não me mostra essas informações (ok, meu homem parece ser específico do debian) ... 'man run-parts' diz que --test não executa os scripts, mas apenas imprime os nomes de eles. Portanto, os scripts nem são testados. Uma coisa menor: 'executável pelo proprietário': Até onde eu sei, os cronjobs são executados apenas como root.
23416 Alex

-1

Estou usando o Webmin porque é uma jóia de produtividade para alguém que considera a administração da linha de comando um pouco assustadora e impenetrável.

Há um botão "Salvar e executar agora" na interface da web "Sistema> Trabalhos agendados do Cron> Editar trabalho do Cron".

Ele exibe a saída do comando e é exatamente o que eu precisava.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.