¿Qué hay de malo con estos dos trabajos cron?

13

Tengo los siguientes trabajos cron definidos.

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 correctamente si ejecuto el comando anterior directamente desde la línea de comando. Pero cuando revisé la ejecución del script esta mañana, recibí un correo electrónico que decía (estoy parafraseando porque los eliminé accidentalmente) que los ticks posteriores no se cerraron correctamente.

Mark D
fuente
FYI acabo de volver a probar los trabajos cron y obtuve los siguientes errores. /bin/sh: 1: Syntax error: EOF in backquote substitution Para el primer trabajo cron. /bin/sh: 1: Syntax error: Unterminated quoted string Para el segundo trabajo cron.
Mark D
2
Los backticks están en desuso por esta misma razón; cambiando a $(...)le ayudará a lidiar con los problemas de cotización ...
jasonwryan
1
Definitivamente quieres revisar una pregunta mía. Tiene una respuesta de Stephane Chazelas que explica cómo puede crear un shell interactivo que sea idéntico al entorno que verá su trabajo cron. Si sigue este pequeño procedimiento, recibirá un mensaje y podrá probar su cronjob paso a paso y ver dónde falla. unix.stackexchange.com/a/56503/16841 Seguro que no coincide al 100% con su pregunta, pero puede ayudarlo a solucionar problemas de crontab.
jippie

Respuestas:

14

Recomiendo encarecidamente colocar cualquier trabajo cron no trivial en su propio archivo de script de shell, por muchas razones:

  • Más fácil de depurar: puede ejecutar el script en lugar de copiar y pegar una línea larga, y con la línea shebang correcta, se comporta de manera mucho más predecible que si tuviera los mismos comandos directamente en el crontab
  • Más fácil de leer: no es necesario convertirlo en una sola línea de más de 200 caracteres, puede formatearlo bien para que sea fácil de leer y comprender para todos
  • Agregar el script al control de versiones
janos
fuente
8
Y poner los %caracteres problemáticos en el guión evitará que los cronconviertan en nuevas líneas, que es su verdadero problema.
Ian D. Allen
Estoy en desacuerdo. Tiendes a olvidar qué guión hace qué. Estoy hablando por experiencia.
Sridhar Sarnobat
30

Hay tres causas comunes para que los comandos de trabajo cron se comporten de manera diferente en comparación con los comandos escritos directamente en un shell interactivo, en un orden aproximado de comunidad:

  • Cron proporciona un entorno limitado, por ejemplo, un mínimo $PATHy faltan otras variables esperadas.
  • Cron invoca /bin/shde forma predeterminada, mientras que puede estar utilizando algún otro shell de forma interactiva.
  • Cron trata al %personaje especialmente (se convierte en una nueva línea en el comando).
  • Cron no proporciona un terminal o entorno gráfico.

Debe preceder a todos los %caracteres con a \en un archivo crontab, que le dice a cron que solo ponga un porcentaje en el comando. Recuerde eso cuando use el datecomando en un trabajo 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"

También arreglé algunos problemas de citas:

  • Esto no le estaba causando problemas aparte de la legibilidad, pero no debería usar los backticks para la sustitución de comandos. Use $(…)en su lugar: sus reglas de análisis son más simples.
  • Utilice siempre comillas dobles alrededor de sustituciones de variables y comandos: "$somevariable", "$(somecommand)". Aquí la falta de comillas fue inofensiva porque el datecomando nunca devolvió ningún carácter especial para los formatos que usó, pero debe recordar cuidadosamente qué caracteres son especiales y verificar esto cada vez que deje una sustitución sin comillas. Que sea simple, siempre use comillas dobles a menos que desee que se produzca la división de campos y la generación de nombre de archivo en el resultado.
  • Tenía algunas comillas simples que impedían la expansión en torno a algunas sustituciones de comandos. Use comillas dobles en su lugar.
Gilles 'SO- deja de ser malvado'
fuente
0

Parece que has anidado 'en el muttcomando:

'Eventos de date +%Y-%m-%d --date='last Wednesday'- date +%Y-%m-%d'

Intente usar en "lugar del interno 'para que la instrucción lea

'Eventos de date +%Y-%m-%d --date="last Wednesday"- date +%Y-%m-%d'

Marko Kudjerski
fuente
No estoy seguro de que ese sea el problema. Pero después de intentarlo en ambos trabajos cron, se ejecuta sin ningún éxito.
Mark D