Comment puis-je exécuter `date` à l'intérieur d'un travail cron tab?

117

Je veux créer un fichier journal pour un script cron qui a l'heure actuelle dans le nom du fichier journal. Voici la commande que j'ai essayé d'utiliser:

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

Malheureusement, je reçois ce message quand ça marche:

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

J'ai essayé d'échapper à la datepartie de différentes manières, mais sans trop de chance. Est-il possible que cela se produise en ligne dans un fichier crontab ou dois-je créer un script shell pour le faire?

cwd
la source

Réponses:

180

Réponse courte:

Échapper à la %comme \%:

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

Longue réponse:

Le message d'erreur suggère que le shell qui exécute votre commande ne voit pas le deuxième caractère de tick arrière:

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

Ceci est également confirmé par le deuxième message d'erreur que vous avez reçu lorsque vous avez essayé l'une des autres réponses:

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

La page de manuel crontab confirme que la commande est en lecture uniquement jusqu'au premier %signe non échappé :

Le "sixième" champ (le reste de la ligne) spécifie la commande à exécuter. Toute la partie commande de la ligne, jusqu'à une nouvelle ligne ou un %caractère, sera exécutée par /bin/shou par le shell spécifié dans la SHELLvariable du fichier cronfile. Les signes en pourcentage ( %) de la commande, sauf s'ils sont précédés d'une barre oblique inversée ( \), sont transformés en caractères de nouvelle ligne et toutes les données suivant la première %sont envoyées à la commande en tant qu'entrée standard.

Adam Zalcman
la source
Désolé pour mon ignorance, mais où voyez-vous ces messages d'erreur? Quand je fais 'grep CRON / var / log / syslog', je ne vois aucun message d'erreur, mais cron a échoué - kagda.ru/i/9a016249a39_20-05-2015-09:22:47_9a01.png
Tebe
2
@ Копать_Шо_я_нашел cron enverra un email avec le message d'erreur,
Jasen
3
date +\%Y\ \%m\ \%d\ \%H:\%M:\%S-cronlog
DevilCode
7

Vous pouvez également placer vos commandes dans un fichier shell, puis exécuter le fichier shell avec cron.

jobs.sh

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

cron

0 * * * * sh jobs.sh
Trevi Awater
la source
6

Si vous souhaitez que la chaîne de formatage de la date soit une variable (pour éviter de dupliquer la chaîne entière), n'échappez pas% et ne le mettez pas dans$()

Par exemple, pendant que vous déclarez la chaîne, écrivez simplement:

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

Ensuite, écrivez la déclaration cron avec $($VARIABLE_NAME)comme ceci:

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

Grâce à cyberx86 , sa réponse sur ServerFault pourrait être plus complète:

Gawi - Kai
la source
1
DATEVAR = "date +% Y% m% d_% H% M% S"
Frank Fang
3

Dans cron, vous pouvez utiliser cette syntaxe simple:

*/15 01-09 * * * sh /script.sh >> /home/username/cron_$(date -d"-0 days" +\%Y\%m\%d).log 2>&1
bala4rtraining
la source
Le format de la date de sortie sera rétabli comme suit
cron_20180123.log
(1) Qu'est-ce que vous dites qui n'a pas déjà été dit par la réponse acceptée? (2) Votre réponse est beaucoup plus compliquée que la question. Par exemple, vous avez ajouté l' -doption, qui n'est pas utilisée dans la question (et vous ne l'avez pas expliquée). Comment justifiez-vous appeler cette "syntaxe simple"?
G-Man
2

Toutes les réponses ci-dessus utilisent des guillemets doubles (ils n’ont pas tous fonctionné pour ma configuration). Cela a fonctionné pour moi:

0 5 * * 3 /data/script.sh > /data/script_`date +\%y\%m\%d`.log 2>&1
Manuel Schmitzberger
la source
1
Que dites-vous qui n'a pas déjà été dit par la réponse acceptée? Voulez-vous dire que cela fonctionne mieux sans guillemets qu'avec des guillemets? (Indice: c'est très peu probable.)
G-Man
La réponse acceptée ne fonctionne tout simplement pas pour moi. Celui-ci fait.
Manuel Schmitzberger
0

Une solution de base:

  • utiliser $()pour exécuter la datecommande et retourner la sortie
  • formater date-heure en UTC, échapper le %caractère avec\
  • ajouter 2>&1à la fin pour la diffusion en continu stdoutet stderrdans ce fichier journal

Exemple:

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

Sortie:

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
la source