Como posso executar `date` dentro de um trabalho da guia cron?

117

Eu quero criar um arquivo de log para um script cron que tenha a hora atual no nome do arquivo de log. Este é o comando que tentei usar:

0 * * * * echo hello >> ~/cron-logs/hourly/test`date "+%d"`.log

Infelizmente, recebo esta mensagem quando é executada:

/bin/sh: -c: line 0: unexpected EOF while looking for matching ``'
/bin/sh: -c: line 1: syntax error: unexpected end of file

Eu tentei escapar da dateparte de várias maneiras, mas sem muita sorte. É possível fazer isso acontecer em linha em um arquivo crontab ou preciso criar um shell script para fazer isso?

cwd
fonte

Respostas:

180

Resposta curta:

Escape do %as \%:

0 * * * * echo hello >> ~/cron-logs/hourly/test`date "+\%d"`.log

Resposta longa:

A mensagem de erro sugere que o shell que executa seu comando não vê o segundo caractere de retorno:

/bin/sh: -c: line 0: unexpected EOF while looking for matching '`'

Isso também é confirmado pela segunda mensagem de erro que você recebeu quando tentou uma das outras respostas:

/bin/sh: -c: line 0: unexpected EOF while looking for matching ')'

A página de manual do crontab confirma que o comando é lido somente até o primeiro %sinal sem escape :

O campo "sexto" (o restante da linha) especifica o comando a ser executado. Toda a parte do comando da linha, até uma nova linha ou %caractere, será executada pelo /bin/shou pelo shell especificado na SHELLvariável do cronfile. Os sinais de porcentagem ( %) no comando, a menos que sejam escapados com barra invertida ( \), serão alterados para caracteres de nova linha e todos os dados após o primeiro %serão enviados ao comando como entrada padrão.

Adam Zalcman
fonte
Desculpe por minha ignorância, mas onde você vê essas mensagens de erro? Quando eu faço 'grep CRON / var / log / syslog', não vejo mensagens de erro, embora o cron falhe
Tebe:
2
@ Копать_Шо_я_нашел cron envia um email com a mensagem de erro,
Jasen
3
date +\%Y\ \%m\ \%d\ \%H:\%M:\%S-cronlog
DevilCode 04/04
7

Você também pode colocar seus comandos em um arquivo shell e, em seguida, executar o arquivo shell com cron.

jobs.sh

echo hello >> ~/cron-logs/hourly/test`date "+%d"`.log

cron

0 * * * * sh jobs.sh
Trevi Awater
fonte
6

Se você deseja transformar a string de formatação de data como uma variável (para evitar duplicar a string inteira), NÃO escape %e NÃO a coloque em$()

Por exemplo, enquanto declara a string, basta escrever:

DATEVAR=date +%Y%m%d_%H%M%S

Em seguida, escreva a instrução cron com o $($VARIABLE_NAME)seguinte:

* * * * * /bin/echo $($DATEVAR) >> /tmp/crontab.log

Graças ao cyberx86 , sua resposta na ServerFault pode ser mais completa:

Gawi - Kai
fonte
1
DATEVAR = "data +% Y% m% d_% H% M% S"
Frank Fang
3

No cron, você pode usar esta sintaxe simples:

*/15 01-09 * * * sh /script.sh >> /home/username/cron_$(date -d"-0 days" +\%Y\%m\%d).log 2>&1
bala4rtraining
fonte
O formato da data de saída será executado novamente como cron_20180123.log
bala4rtraining
(1) O que você está dizendo que ainda não foi dito pela resposta aceita? (2) Sua resposta é muito mais complicada do que a pergunta. Por exemplo, você adicionou a -dopção, que não é usada na pergunta (e você não a explicou). Como você justifica chamar essa "sintaxe simples"?
G-Man
2

Todas as respostas acima usam aspas duplas (nem todas funcionaram na minha configuração). Isso funcionou para mim:

0 5 * * 3 /data/script.sh > /data/script_`date +\%y\%m\%d`.log 2>&1
Manuel Schmitzberger
fonte
1
O que você está dizendo que ainda não foi dito pela resposta aceita? Você está dizendo que funciona melhor sem aspas do que com aspas? (Dica: isso é muito improvável.)
G-Man
A resposta aceita simplesmente não funciona para mim. Este faz.
Manuel Schmitzberger
0

Uma solução básica:

  • use $()para executar datecomando e retornar saída
  • formato datetime para UTC, escape o %caractere com\
  • adicione 2>&1no final para transmitir ambos stdoute stderrpara esse arquivo de log

Exemplo:

* * * * * echo "Test crontab log" > /tmp/crontab.log.$(date --utc +\%Y\%m\%d_\%H\%M\%SZ) 2>&1

Resultado:

ls -lh /tmp | grep log

-rw-rw-r-- 1 ubuntu  ubuntu    17 May  4 05:06 crontab.log.20190504_050601Z
-rw-rw-r-- 1 ubuntu  ubuntu    17 May  4 05:07 crontab.log.20190504_050701Z
Hieu Huynh
fonte