Вопрос или проблема
Вот моя команда crontab:
*/15 * * * * cd /home/ec2-user/SageMaker && /bin/bash /home/ec2-user/SageMaker/churn_end_to_end_pipeling_actionable.sh
В моем письме вот ошибки, которые я получаю:
Message-Id: <[email protected]>
X-Authentication-Warning: ip-172-16-124-135.ec2.internal: ec2-user set sender to root using -f
From: [email protected] (Cron Daemon)
To: [email protected]
Subject: Cron <ec2-user@ip-172-16-124-135> cd /home/ec2-user/SageMaker && /bin/bash /home/ec2-user/SageMaker/churn_end_to_end_pipeling_actionable.sh
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
X-Cron-Env: <LANG=en_US.UTF-8>
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/ec2-user>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=ec2-user>
X-Cron-Env: <USER=ec2-user>
Traceback (most recent call last):
File "feature_engineering.py", line 9, in <module>
import seaborn as sns
ImportError: No module named seaborn
Traceback (most recent call last):
File "generate_churn_outputs_actionable.py", line 5, in <module>
from xgboost import XGBClassifier
ImportError: No module named xgboost
Я не уверен, почему я сталкиваюсь с этой ошибкой, так как я выполнял sudo -H pip install <package>
перед запуском задания cron.
Также вот содержимое моего bash-скрипта и python-скриптов, на которые он ссылается:
Bash:
#!/bin/bash
python feature_engineering.py
python generate_churn_outputs_actionable.py 1
Скрипт 1 и 2:
#! /home/ec2-user/anaconda3/envs/JupyterSystemEnv/bin/python
Буду признателен за любую помощь. Если я что-то упустил, дайте знать, и я добавлю это.
У меня была такая же проблема на Ubuntu 18.04, и явный путь в crontab не сработал. По какой-то причине cron не работал, а sudo из моего аккаунта работал. Я предполагал, что они должны быть одинаковыми, но, увы, это не так. Я пришел к выводу, что это проблема с переменными окружения.
Вы можете смоделировать проблему с cron в sudo, выполнив следующее:
sudo bash -c "HOME=FOO;python3 -c \"import xgboost\""
Для меня решением было вызвать shell-скрипт из crontab, который затем выполняет python-скрипт. Также нужно было установить переменные окружения HOME и PYTHONPATH:
crontab:
# Выполнить shell-скрипт и перенаправить stdout и stderr в лог-файл
# Это позволит вам увидеть, что происходит в реальном времени
* * * * * <ваш_путь>/yourscript.sh >> <ваш_путь>yourscript_cron.log 2>&1
yourscript.sh:
#!/bin/bash
echo yourscript.sh вызван: `date`
HOME=<ваша_домашняя_директория>
PYTHONPATH=<путь_к_пакетам_распределения>
cd <путь_к_вашему_python_скрипту>
<python_исполняемый_файл> ./<ваш_python_скрипт> 2>&1 1>/dev/null
Ответ или решение
Приветствую вас!
Ситуация, с которой вы столкнулись, довольно распространена при работе с cron и Python-пакетами на системах, использующих среду выполнения, например, Anaconda или виртуальные окружения. Давайте разберемся с причиной проблемы и предложим решения.
1. Причина проблемы
Основная причина ваших ошибок, таких как ImportError: No module named seaborn
и ImportError: No module named xgboost
, заключается в том, что cron выполняет ваши задачи в более ограниченной среде, чем ваша обычная пользовательская среда.
-
Привилегии и окружение: Когда вы выполняете команды с
sudo
, Python использует системные модули и установленные пакеты в зависимости от текущего окружения пользователя. Когда вы запускаете скрипты из cron, они могут не видеть те же пути, что и ваш пользовательский сеанс, так как cron использует ограниченный набор переменных среды (например,PATH
). -
Отсутствие переменных окружения: Для скриптов, которые требуют специфические переменные окружения, такие как
PYTHONPATH
, cron может не обнаружить эти переменные, если вы не установите их вручную в вашем скрипте.
2. Решения
Использование полного пути к интерпретатору Python
Во-первых, убедитесь, что вы используете полный путь к вашему интерпретатору Python в скрипте:
#! /home/ec2-user/anaconda3/envs/JupyterSystemEnv/bin/python
Это гарантирует, что нужный интерпретатор будет использован специфически в вашем скрипте.
Создание оболочки для скрипта
Рекомендуется создать оболочку для вашего скрипта и явно установить все нужные переменные среды. Вот как это можно сделать:
- Создайте новый shell-скрипт, например
run_scripts.sh
:
#!/bin/bash
# Установите переменные окружения
export HOME=/home/ec2-user
export PYTHONPATH=/home/ec2-user/anaconda3/envs/JupyterSystemEnv/lib/python3.X/site-packages
# Перейдите в директорию со скриптом
cd /home/ec2-user/SageMaker
# Запустите Python-скрипты
/home/ec2-user/anaconda3/envs/JupyterSystemEnv/bin/python feature_engineering.py
/home/ec2-user/anaconda3/envs/JupyterSystemEnv/bin/python generate_churn_outputs_actionable.py 1
Не забудьте заменить python3.X
на вашу актуальную версию Python.
- Затем измените ваш
crontab
, чтобы он вызывал этот скрипт:
*/15 * * * * /home/ec2-user/SageMaker/run_scripts.sh >> /home/ec2-user/SageMaker/script.log 2>&1
Это перенаправит стандартный вывод и ошибки вашего скрипта в лог-файл, что поможет вам следить за выполнением и отладкой.
Проверка прав доступа
Убедитесь, что у вас есть необходимые права доступа на выполнение вашего скрипта. Вы можете сделать это с помощью:
chmod +x /home/ec2-user/SageMaker/run_scripts.sh
3. Заключение
Изменения, предложенные в этом ответе, должны помочь вам избежать ошибок импорта пакетов при запуске скриптов через cron. Убедитесь, что все пути прописаны корректно, а переменные окружения установлены.
Если у вас остаются вопросы или потребуются дальнейшие разъяснения, не стесняйтесь задавать их. Удачи в вашей работе!