Quel est le problème avec ces deux tâches cron?

13

J'ai les tâches cron suivantes définies.

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'

Il semble fonctionner correctement si je l'exécute la commande ci-dessus directement à partir de la ligne de commande. Mais quand j'ai vérifié le déroulement du script ce matin, j'ai reçu un e-mail m'indiquant (je paraphrase parce que je les ai accidentellement supprimés) que les ticks arrière n'étaient pas fermés correctement.

Mark D
la source
Pour info, je viens de retester les tâches cron et j'ai obtenu les erreurs suivantes. /bin/sh: 1: Syntax error: EOF in backquote substitution Pour le premier travail cron. /bin/sh: 1: Syntax error: Unterminated quoted string Pour le deuxième travail cron.
Mark D
2
Les backticks sont déconseillés pour cette raison même; changer pour $(...)vous aider à résoudre les problèmes de citation ...
jasonwryan
1
Vous voulez vraiment vérifier une de mes questions. Il a une réponse de Stéphane Chazelas qui explique comment vous pouvez créer un shell interactif identique à l'environnement que verra votre tâche cron. Si vous parcourez sa petite procédure, vous obtenez une invite et vous pouvez tester votre cronjob étape par étape et voir où il échoue. unix.stackexchange.com/a/56503/16841 Bien sûr, ce n'est pas une correspondance à 100% pour votre question, mais cela peut vous aider à résoudre les problèmes de crontab.
jippie

Réponses:

14

Je recommande fortement de placer tous les travaux cron non triviaux dans leur propre fichier de script shell, pour plusieurs raisons:

  • Plus facile à déboguer: vous pouvez simplement exécuter le script au lieu de copier-coller une longue ligne, et avec la bonne ligne de shebang, il se comporte de manière beaucoup plus prévisible que si vous aviez les mêmes commandes directement dans la crontab
  • Plus facile à lire: pas besoin d'en faire un monoligne de plus de 200 caractères, vous pouvez le formater bien pour qu'il soit facile à lire et à comprendre pour tout le monde
  • Ajouter le script au contrôle de version
janos
la source
8
Et mettre les %caractères gênants dans le script empêchera de les crontransformer en nouvelles lignes, ce qui est votre vrai problème.
Ian D. Allen
Je ne suis pas d'accord. Vous avez tendance à oublier quel script fait quoi. Je parle d'expérience.
Sridhar Sarnobat
30

Il existe trois causes courantes pour lesquelles les commandes cron job se comportent différemment des commandes saisies directement dans un shell interactif, dans un ordre approximatif de commun:

  • Cron fournit un environnement limité, par exemple, un minimum $PATHet d'autres variables attendues manquantes.
  • Cron invoque /bin/shpar défaut, alors que vous utilisez peut-être un autre shell de manière interactive.
  • Cron traite le %personnage spécialement (il est transformé en nouvelle ligne dans la commande).
  • Cron ne fournit pas d'environnement terminal ou graphique.

Vous devez faire précéder tous les %caractères d'un \dans un fichier crontab, qui indique à cron de simplement mettre un pourcentage dans la commande. N'oubliez pas que lorsque vous utilisez la datecommande dans une tâche 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"

J'ai également corrigé quelques problèmes de citation:

  • Cela ne vous causait pas de problèmes autres que la lisibilité, mais vous ne devriez pas utiliser de backticks pour la substitution de commandes. Utilisez $(…)plutôt: ses règles d'analyse sont plus simples.
  • Utilisez toujours des guillemets doubles autour des substitutions de variables et de commandes: "$somevariable", "$(somecommand)". Ici, l'absence de guillemets était inoffensive car la datecommande n'a jamais renvoyé de caractère spécial pour les formats que vous avez utilisés, mais vous devez vous rappeler soigneusement quels caractères sont spéciaux et vérifier cela chaque fois que vous laissez une substitution sans guillemets. Restez simple, utilisez toujours des guillemets doubles, sauf si vous souhaitez que le fractionnement des champs et la génération du nom de fichier se produisent sur le résultat.
  • Vous aviez des guillemets simples empêchant l'expansion autour de certaines substitutions de commandes. Utilisez plutôt des guillemets doubles.
Gilles 'SO- arrête d'être méchant'
la source
0

Vous semblez avoir imbriqué 'dans la muttcommande:

«Événements de date +%Y-%m-%d --date='last Wednesday'- date +%Y-%m-%d»

Essayez d'utiliser à la "place de l'intérieur 'pour que l'instruction indique

«Événements de date +%Y-%m-%d --date="last Wednesday"- date +%Y-%m-%d»

Marko Kudjerski
la source
Je ne suis pas sûr que ce soit le problème. Mais après l'avoir essayé dans les deux tâches cron, l'exécuter sans succès.
Mark D