Что не так с этими двумя заданиями cron?

13

У меня определены следующие задания 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'

Кажется, он работает правильно, если я запускаю приведенную выше команду непосредственно из командной строки. Но когда я проверил выполнение скрипта этим утром, я получил электронное письмо с сообщением (я перефразирую, потому что я случайно удалил их), что обратные галочки не были закрыты должным образом.

Марк Д
источник
К вашему сведению, я только что перепробовал задания cron и получил следующие ошибки. /bin/sh: 1: Syntax error: EOF in backquote substitution Для первой работы cron. /bin/sh: 1: Syntax error: Unterminated quoted string Для второй работы cron.
Марк Д
2
Backticks устарели по этой самой причине; переход на $(...)поможет вам справиться с проблемами цитирования ...
jasonwryan
1
Вы определенно хотите проверить мой вопрос. Он содержит ответ Stephane Chazelas, который объясняет, как вы можете создать интерактивную оболочку, идентичную среде, которую увидит ваша работа cron. Если вы пройдете его маленькую процедуру, вы получите подсказку и сможете шаг за шагом протестировать ваш cronjob и посмотреть, где он не работает. unix.stackexchange.com/a/56503/16841 Конечно, это не на 100% соответствует вашему вопросу, но может помочь вам решить проблемы crontab.
Джиппи

Ответы:

14

Я настоятельно рекомендую помещать любые нетривиальные задания cron в свой собственный файл сценария оболочки по многим причинам:

  • Проще отладить: вы можете просто запустить скрипт, а не копировать, вставляя длинную строку, а с правильной строкой shebang он ведет себя гораздо более предсказуемо, чем если бы вы имели те же команды непосредственно в crontab
  • Легче читать: не нужно указывать более 200 символов в одну строку, вы можете красиво отформатировать его, чтобы его легко было прочитать и понять всем
  • Добавить скрипт в систему контроля версий
Янош
источник
8
А введение %в сценарий проблемных персонажей не позволит cronпревращать их в новые строки, что является вашей реальной проблемой.
Ян Д. Аллен
Я не согласен. Вы склонны забывать, какой сценарий делает что. Я говорю из опыта.
Шридхар Сарнобат
30

Команды заданий cron ведут себя по-разному по сравнению с командами, введенными непосредственно в интерактивную оболочку, в грубом порядке:

  • Cron предоставляет ограниченную среду, например, минимальную $PATH, а другие ожидаемые переменные отсутствуют.
  • Cron вызывается /bin/shпо умолчанию, тогда как вы можете использовать какую-то другую оболочку в интерактивном режиме.
  • Крон обрабатывает %персонажа специально (он превращается в новую строку в команде).
  • Cron не предоставляет терминальную или графическую среду.

Вы должны предшествовать всем %символам \в файле crontab с символом a , который говорит cron просто ввести процент в команду. Помните об этом, когда вы используете dateкоманду в задании 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"

Я также исправил некоторые проблемы с цитированием:

  • Это не вызывало у вас проблем кроме разборчивости, но вы не должны использовать обратные пометки для подстановки команд. Используйте $(…)вместо этого: его правила разбора проще.
  • Всегда используйте двойные кавычки вокруг переменных и подстановок команд: "$somevariable", "$(somecommand)". Здесь отсутствие кавычек было безобидным, потому что dateкоманда никогда не возвращала никаких специальных символов для используемых вами форматов, но вы должны тщательно помнить, какие символы являются специальными, и проверять это каждый раз, когда оставляете подстановку без кавычек. Проще говоря, всегда используйте двойные кавычки, если вы не хотите, чтобы в результате происходило разбиение поля и генерация имени файла.
  • У вас было несколько одинарных кавычек, препятствующих расширению вокруг некоторых подстановок команд. Вместо этого используйте двойные кавычки.
Жиль "ТАК - прекрати быть злым"
источник
0

Вы, кажется, вложили 'в muttкоманду:

«События от date +%Y-%m-%d --date='last Wednesday'- date +%Y-%m-%d»

Попробуйте использовать "вместо внутреннего, 'чтобы оператор читал

«События от date +%Y-%m-%d --date="last Wednesday"- date +%Y-%m-%d»

Марко Куджерски
источник
Я не уверен, что в этом проблема. Но после того, как он выполнил задание на обоих заданиях cron, выполнить его не удалось.
Марк Д