O que há de errado com essas duas tarefas do cron?

12

Eu tenho as seguintes tarefas cron definidas.

55  8   *   *   3   /usr/bin/php /home/mark/dev/processes/customClient/events.php > /home/mark/dev/processes/customClient/events-'date +%Y-%m-%d --date='last Wednesday''-'date +%Y-%m-%d'.csv
0   9   *   *   3   /usr/bin/echo 'The csv for last week, trying my hand at automatiging this' | /usr/bin/mutt <emailaddress> -s 'Events from 'date +%Y-%m-%d --date='last Wednesday''-'date +%Y-%m-%d'' -a '/home/mark/dev/processes/customClient/events-'date +%Y-%m-%d --date='last Wednesday''-'date +%Y-%m-%d'.csv'

Parece funcionar corretamente se eu executar o comando acima diretamente da linha de comando. Mas quando chequei a execução do roteiro esta manhã, recebi um e-mail dizendo (estou parafraseando porque acidentalmente os deletei) que os sinais de trás não estavam fechados corretamente.

    
por Mark D 12.09.2012 / 15:59

3 respostas

12

Eu recomendo strongmente colocar qualquer tarefa cron não trivial em seu próprio arquivo de script de shell, por várias razões:

  • Mais fácil de depurar: você pode simplesmente executar o script em vez de copiar uma linha longa, e com a linha direita shebang, ele se comporta de maneira muito mais previsível do que se você tivesse os mesmos comandos diretamente no crontab
  • Mais fácil de ler: não é necessário criar um modelo com mais de 200 caracteres, você pode formatá-lo bem para facilitar a leitura e a compreensão para todos
  • Adicione o script ao controle de versão
por 12.09.2012 / 22:14
25

Existem três causas comuns para os comandos do cron job se comportarem de maneira diferente em comparação com os comandos digitados diretamente em um shell interativo, em uma ordem aproximada de commonness:

  • O Cron fornece um ambiente limitado, por exemplo, um $PATH mínimo e outras variáveis esperadas ausentes.
  • O Cron invoca /bin/sh por padrão, enquanto você pode estar usando algum outro shell interativamente.
  • Cron trata o caractere % especialmente (ele é transformado em uma nova linha no comando).
  • O Cron não fornece um terminal ou ambiente gráfico.

Você deve preceder todos os caracteres % com um \ em um arquivo crontab, que informa ao cron para colocar apenas um percentual no comando. Lembre-se de que quando você usa o comando date em uma tarefa cron.

55  8   *   *   3   /usr/bin/php /home/mark/dev/processes/customClient/events.php > "/home/mark/dev/processes/customClient/events-$(date +\%Y-\%m-\%d --date='last Wednesday')-$(date +\%Y-\%m-\%d).csv"
0   9   *   *   3   /usr/bin/echo 'The csv for last week, trying my hand at automatiging this' | /usr/bin/mutt <emailaddress> -s "Events from $(date +\%Y-\%m-\%d --date='last Wednesday')-$(date +\%Y-\%m-\%d)" -a "/home/mark/dev/processes/customClient/events-$(date +\%Y-\%m-\%d --date='last Wednesday')-$(date +\%Y-\%m-\%d).csv"

Também consertei alguns problemas de cotação:

  • Isso não estava causando outros problemas além da legibilidade, mas você não deve usar backticks para a substituição de comandos. Use $(…) : suas regras de análise são mais simples.
  • Sempre use aspas duplas em torno das substituições de comando e variável: "$somevariable" , "$(somecommand)" . Aqui a falta de aspas era inofensiva porque o comando date nunca retornou nenhum caractere especial para os formatos que você usou, mas é preciso lembrar cuidadosamente quais caracteres são especiais e verificar isso toda vez que você deixar uma substituição sem aspas. Mantenha-o simples, use sempre aspas duplas, a menos que você queira que a divisão de campos e geração de nome de arquivo ocorra no resultado.
  • Você tinha algumas aspas simples impedindo a expansão em torno de algumas substituições de comandos. Use aspas duplas.
por 13.09.2012 / 00:57
0

Parece que você aninhou ' no comando mutt :

'Events from date +%Y-%m-%d --date='last Wednesday'-date +%Y-%m-%d'

Tente usar " em vez do interior ' para que a declaração seja lida

'Events from date +%Y-%m-%d --date="last Wednesday"-date +%Y-%m-%d'

    
por 12.09.2012 / 16:28