Я написал различные сценарии для запуска серверных приложений Java, которые обычно запускаются в течение 24 часов перед отключением (путем вызова того же сценария с другим параметром).
Скрипт полагается на переменные среды, определенные в файле: ~/<user>.env
, который я получил из .bashrc
.
Это отлично работает при вызове сценария из командной строки, но если я хочу добавить сценарий как запись crontab, я сталкиваюсь с проблемой, когда .bashrc
не читается.
Мой вопрос: как лучше всего решить эту проблему? Я понимаю, что могу определить запись crontab, например:
* * * * 1-5 /usr/bin/bash -c '. /home/myuser/myuser.env && /home/myuser/scripts/myscript.sh'
... но это кажется ужасным. В качестве альтернативы я мог бы найти myuser.env
в начале каждого сценария, но поддерживать это стало бы кошмаром.
Любая помощь приветствуется.
Обычно я обращаюсь к этому с помощью короткого сценария-оболочки cron:
#!/bin/bash
[ -r $HOME/.bashrc ] && . $HOME/.bashrc
[ -r $HOME/.profile ] && . $HOME/.profile
exec "$@"
Затем просто добавьте к команде в crontab префикс вашей оболочки:
* * * * 1-5 ~/scripts/cron-wrapper ~/scripts/myscript.sh
* * * * 1-5 ~/scripts/cron-wrapper ~/scripts/myotherscript.sh
Некоторые версии cron позволяют устанавливать переменные прямо в crontab. К сожалению, я не могу их использовать на работе.
На самом деле я обнаружил довольно элегантное решение, добавив флаг '-l' (--login) к моей команде bash, которая заставляет ее использовать все файлы входа в систему, включая .bashrc. Следовательно, моя команда crontab проста:
* * * * 1-5 /usr/bin/bash -lc '/mnt/group/core/deploy/scripts/test.sh' > /dev/null 2>&1
Альтернативным (хотя и не обязательно лучшим) вариантом было бы добавить их в crontab суперпользователя и указать в записи su с тире, чтобы стать соответствующим пользователем. Затем переменные среды будут автоматически извлечены через среду оболочки пользователя по умолчанию в ~ / .bashrc или т.п. например:
* * * * 1-5 su - scriptuser '/home/myuser/scripts/myscript.sh'
Это запустит задание от имени пользователя сценария со всеми переменными среды для правильного входа в систему. Обратной стороной является то, что сам скрипт-пользователь не мог настроить это задание - для этого потребовались бы права root.
Решение cron-wrapper у меня сработало с одной модификацией, мне нужно было заменить $ HOME на абсолютный путь к домашней папке пользователя, в данном случае это было:
#!/bin/bash
[ -r /root/.bashrc ] && . /root/.bashrc
[ -r /root/.profile ] && . /root/.profile
exec "$@"
Единственное, что я могу придумать, было бы основано на:
bash -i --rcfile 'init' -c 'script'
что, вероятно, менее привлекательно.
Последние версии cron позволяют задавать произвольные переменные среды перед запуском заданий. Итак, вы можете добавить это в свой crontab:
CRON = 1
Затем в вашем .bash_login сделайте что-то вроде этого:
[-n "$ CRON"] &&. .bashrc