Переменные в 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
Что похоже на то, что вы хотели.