Вопрос или проблема
Здравствуйте, не могли бы вы помочь?
Я запускаю скрипт в WSL, который требует присутствия автоматически загружаемых переменных хоста, когда crontab выполняется, он работает, когда я вхожу в систему пользователя, однако не работает, когда я запускаю свою cron-задачу.
@reboot sleep 10 && /home/jon/autoproxy.sh >> /var/log/autoproxy.log 2>&1
Я пытался задержать выполнение скрипта до полной загрузки машины, однако он не видит автоматически заполненные переменные среды пользователя.
Кто-нибудь знает, как это сделать?
Это зависит от того, где определены переменные (глобально, для пользователя, в оболочке, systemd, pam и т.д.).
Первый шаг – это
. /etc/profile
Вы можете начать с проверки, какие переменные актуальны для вашего скрипта и где они определены.
.
Ответ или решение
Запуск cron-задачи с полными переменными окружения пользователя является распространенной задачей, особенно в контексте работы на Windows Subsystem for Linux (WSL). Когда вы запускаете скрипт из-под cron, окружение отличается от того, которое доступно при интерактивном входе пользователя в систему, что может вызывать проблемы с доступностью определённых переменных.
Теория
Когда вы запускаете процессы через cron, они используют ограниченное окружение по умолчанию. Это окружение обычно гораздо проще, чем то, которое загружается во время интерактивного входа в систему пользователя. Это связано с тем, что cron не запускает скрипты загрузки профилей оболочки, такие как .bashrc
, .bash_profile
, или .profile
, которые обычно инициализируют переменные окружения и другую важную конфигурацию.
В Unix-подобных системах переменные окружения могут быть определены в нескольких местах:
- Глобальные переменные: Обычно устанавливаются в файлах вроде
/etc/environment
или/etc/profile
. - Переменные пользователя: Загружаются из файлов вроде
~/.bashrc
,~/.bash_profile
,~/.profile
, и других. - Переменные специфичного сеанса: Устанавливаются непосредственно в сеансе оболочки и не сохраняются после его завершения.
Пример
Рассмотрим следующее: супозиторий @reboot sleep 10 && /home/jon/autoproxy.sh >> /var/log/autoproxy.log 2>&1
работает неправильно, так как не имеет доступа к нужным переменным окружения. Чтобы обеспечить скрипт нужными переменными окружения, нужно явно их загрузить перед выполнением скрипта.
Применение
Вот несколько практических шагов, которые помогут вам решить проблему:
-
Ручное задание переменных окружения в crontab: Вы можете включить переменные окружения непосредственно в crontab. Если ваши переменные известны и неизменны, вы можете задать их выше строки задания в crontab:
VARIABLE_NAME=value @reboot sleep 10 && /home/jon/autoproxy.sh >> /var/log/autoproxy.log 2>&1
-
Загрузка профиля пользователя: Вы можете загрузить ваш профайл оболочки перед выполнением скрипта. Включите команду для загрузки профиля в crontab:
@reboot sleep 10 && . /home/jon/.profile && /home/jon/autoproxy.sh >> /var/log/autoproxy.log 2>&1
(Обратите внимание на пробел после точки.)
-
Скрещивание подходов (используя wrapper-script): Создайте обертку для вашего скрипта, которая сначала загружает необходимые переменные, а затем вызывает основной скрипт:
#!/bin/bash . /etc/profile . ~/.bashrc /home/jon/autoproxy.sh
И измените ваш crontab:
@reboot sleep 10 && /home/jon/autoproxy_wrapper.sh >> /var/log/autoproxy.log 2>&1
-
Использование служебных файлов systemd: Поскольку вы используете WSL, перед вами может стоять возможность использовать systemd для более сложного задания, чем стандартный cron. Systemd может наследовать переменные окружения пользователя, если вы создадите файл сервиса и сделаете его исполняемым в соответствующее время.
-
Проверка необходимости всех переменных: Убедитесь, что вам действительно нужны все переменные для этого скрипта. Иногда все нужные зависимости можно минимизировать, если быть точным касательно того, какие переменные критичны для выполнения.
Одна из основных задумок в этой теме – оптимально обработать источники переменных окружения так, чтобы их доступность при выполнении cron-задания была такой же, как и в интерактивной сессии. Этот подход обеспечивает правильное выполнение скрипта при грузиовке системы без участия пользователя.