заставить Cron работать в той же среде, что и при входе по ssh

заставить Cron работать в той же среде, что и при входе по ssh

У меня есть скрипт, который отлично работает, когда я подключаюсь по 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
...

Связанный контент