Переменные в crontab?

Как я могу хранить переменные в моем crontab? Я понимаю, что это не оболочка, но говорю, что хочу иметь некоторые константы, такие как путь к моему приложению или что-то в этом роде?

Мысли?

7 ответов

Решение

В Vixie cron, который, возможно, является наиболее распространенным, вы можете сделать это почти так же, как сценарий оболочки.

VARIABLE=value
PATH=/bin:/path/to/doathing
0 0 * * * doathing.sh $VARIABLE

На странице руководства написано:

Активной строкой в ​​crontab будет либо настройка среды, либо команда cron. Окружение настройки имеет вид,

     name = value

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

Вы можете узнать, есть ли у вас Vixie cron, проверив страницу руководства для crontab; автором будет Пол Викси. Различные cron могут поддерживать или не поддерживать это (например, cron BusyBox не поддерживает), и в этом случае ваш лучший вариант - заключить команду в сценарий оболочки и запустить вместо этого этот сценарий из cron. На самом деле, это хорошо для всего сложного.

Чтобы сохранить мой crontab в чистоте, я бы просто вызвал скрипт оболочки и сделал забавные вещи в скрипте.

Я думаю, что здесь важно отметить (как указано в более раннем комментарии Пьера Д. 25 марта 2015 г., 18:58), что объявления переменных не расширяются/интерполируются и поэтому не могут встраивать другие значения переменных.

Переменные расширяются/интерполируются только в самих командах.

Так:

      var1 = bar
var2 = foo${var1}
42 17 * * * /path/to/command ${var2}

Результат: /path/to/command foo${var1}

Пока:

      var1 = bar
var2 = foo
42 17 * * * /path/to/command ${var2}${var1}

Результат: /path/to/command foobar

Итак, в моем случае следующее работает нормально, не требуется обертка в сценарии оболочки:

      SHELL=/bin/bash
timestamp=date +20%y_%m_%d_%H_%M_%S
logdir=/my/log/dir

0 2 * * * /my/command/path/mycmd param >> ${logdir}/myfile_$(${timestamp}).log

стихи примерно такие, которые не работают:

      logfile = /my/log/dir/myfile_${timestamp}.log

поскольку последний не расширяется, а скорее интерпретируется как включение «${» и «}» как части строки.

Просто рабочий пример использования переменных в crontab файл и их подстановка в строках:

      CURRENT_TIME=date +%Y.%m.%d_%H:%M:%S.%3N
CURRENT_DATE=date +%Y_%m_%d

SIMPLE_VAR=the_simple_var
LOG_DIR=/var/log/cron

* * * * * /bin/echo "simple variable test! ${SIMPLE_VAR}__test!" >> "${LOG_DIR}/test.log"
* * * * * /bin/echo "complex variable test! $(${CURRENT_TIME})__test!" >> "${LOG_DIR}/test.log"

Протестировано на этом образе Docker (вставьте указанный выше crontab в crontab.txt):

      FROM debian:10-slim

# Install docker (Yep, this is a docker in docker):
RUN curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh

# Install CRON:
RUN apt-get update && apt-get install -y --no-install-recommends cron

# Add a crontab_config.txt task:
COPY crontab.txt /var/crontab.txt
RUN crontab /var/crontab.txt

ENTRYPOINT ["cron", "-f"]

Добавьте это в crontab, чтобы запускать любые команды внутри других контейнеров докеров:

      /usr/bin/docker exec container_name ls -la

Если у вас есть несколько переменных среды, которые вы хотите установить для определенного задания, просто вставьте их во фрагмент.

      42 17 * * * myvariable='value' path/to/command

Если это не очевидно, sh синтаксис var=value command наборы var к value на время command. У вас может быть несколько штук, если вам нужно больше одного.

      42 17 * * * firstname='Fred` lastname='Muggs' path/to/command

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

Допустим, у вас есть файл $HOME/bin/myenv с такими настройками, как

      myvar=$(output of some complex command)
another='another
complex
variable'

тогда вы можете добавить

      . $HOME/bin/myenv

на ваш .profile (или же .zshrc или же .bash_profile or what have you; but .профиль is portable, and also used byш`) и

      42 17 * * * . $HOME/bin/myenv; path/to/command

в твоей .

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

По касательной $HOME/ часть, строго говоря, лишняя; cron задания всегда будут выполняться в домашнем каталоге вызывающего пользователя.

Очевидно, если вы хотите, чтобы переменная была истинной для всего вашего crontab, установите его вверху перед запланированными заданиями.

Вы можете поместить переменные окружения в crontab. Смотрите справочную страницу для crontab(5) Больше подробностей.

Я не очень разбираюсь в Unix, так что я не могу сказать что-либо определенное, но это звучит как хорошее место для этапа предварительной обработки.

#define cmdpath /usr/bin/myfolder/cmd
0,30 8-17 * * 1-5 cmdpath
17 3 * * 1 cmdpath

выполнение этого через препроцессор моего C++ компилятора дает как:

0,30 8-17 * * 1-5 /usr/bin/myfolder/cmd
17 3 * * 1 /usr/bin/myfolder/cmd

Что похоже на то, что вы хотели.

Другие вопросы по тегам