
У меня есть скрипт, который отлично работает, когда я подключаюсь по ssh к своему экземпляру Ubuntu EC2 и запускаю его (как пользователь ubuntu
)
Я хочу, чтобы это происходило при загрузке сервера, поэтому я добавил это в cron следующим образом:
@reboot sleep 10 && /home/ubuntu/start.sh
Однако при запуске cron ситуация PATH
иная, и некоторые команды не выполняются, поскольку двоичные файлы не загружены:
$ echo $PATH
/home/ubuntu/.nvm/versions/node/v4.2.6/bin:/home/ubuntu/bin:/home/ubuntu/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
# in start.sh
echo "path $PATH" >> start.logs
# will log 'path /usr/bin:/bin'
Я попытался добавить source /home/ubuntu/.bashrc
в свой start.sh
сценарий, поскольку я считаю, что именно там PATH
построено, по крайней мере частично, но это, похоже, не сильно меняет ситуацию:
# in start.sh
source /home/ubuntu/.bashrc
echo "path $PATH" >> start.logs
# will still log 'path /usr/bin:/bin'
Я также проверил, что Cron запускается как , ubuntu
а не как root
, что, похоже, так и есть, поскольку я отредактировал задания cron, вошедшие в систему какubuntu
Есть ли простой способ запустить cron в той же среде, в которую я попадаю после входа на свой сервер по SSH?
решение1
Обычно переменные окружения должны быть определены в ~/.profile
, или ~/.bash_profile
если этот файл существует, ваша оболочка входа — bash. Так что загрузите этот файл из задания cron.
@reboot . ~/.profile; sleep 10 && /home/ubuntu/start.sh
~/.bashrc
предназначен только для интерактивных настроек, поэтому вам не следует загружать его неинтерактивно, и обычно он все равно не будет работать. Если у вас есть определения переменных окружения в .bashrc
, исправьте этот беспорядок в первую очередь.
Другое место для установки переменных среды — это ~/.pam_environment
, если вы хотите, чтобы переменная имела постоянное значение (вы не можете запускать команды оболочки в этом файле).
ВидетьКакой наилучший способ настройки переменных окружения, не зависящий от дистрибутива/оболочки?,Разница между оболочкой входа и оболочкой без входа?иСуществует ли эквивалентный файл «.bashrc», читаемый всеми оболочками?для получения дополнительной информации о файлах запуска оболочки.
решение2
cron обычно запускается с sh, а не с bash, у них разные профили.
попробуйте запустить отдельный cron в bash, если у вас есть несколько пользовательских переменных окружения, вы всегда можете env>/file, source /file в cron.
решение3
Я решил свою проблему следующим образом:
- запустить
$ crontab -e
и добавить перед всеми остальными строкамиSHELL=/bin/bash
Это заставит cron использовать bash. Естьальтернативыесли вы хотите сделать это только для одной команды - В файле my
.bashrc
, который был установлен по умолчанию на экземпляре AWS EC2 Ubuntu, были следующие строки:
.
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
так что выполнение source /home/ubuntu/.bashrc
ничего не сделает в задании cron. Кажется, это служит определенной цели, поэтому я не удалил его полностью, а заменил на:
# If not running interactively, don't do anything
if [ -z ${RUN_BASHRC+x} ]; then
echo "might return";
else
case $- in
*i*) ;;
*) return;;
esac
fi
что позволило мне установить флаг, чтобы обойти это раннее возвращение.
- Наконец, по некоторым причинам,
PATH
все еще не был обновлен правильно. Я мог бы исправить это, выполнив:
.
ADDITIONAL_PATH=$(sudo -Hiu ubuntu env | grep -oP "^PATH=\K.*")
PATH=$ADDITIONAL_PATH:$PATH
Я не уверен на 100%, что это делает :) но в итоге я получаю то же самое, что и PATH
при входе через ssh.
Итак, наконец:
кронтаб:
SHELL=/bin/bash
@reboot RUN_BASHRC=1 /home/ubuntu/startup.sh >> /home/ubuntu/cron-startup.logs
~/.bashrc
: замена выше
~/start.sh
:
#!/bin/bash
ADDITIONAL_PATH=$(sudo -Hiu ubuntu env | grep -oP "^PATH=\K.*")
PATH=$ADDITIONAL_PATH:$PATH
...