让 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如果该文件存在,则您的登录 shell 是 bash。因此,从 cron 作业加载此文件。

@reboot . ~/.profile; sleep 10 && /home/ubuntu/start.sh

~/.bashrc仅用于交互式自定义,因此您不应该以非交互式方式加载它,而且它通常无论如何也不会工作。如果您在 中有环境变量定义.bashrc,请先解决这个问题。

设置环境变量的另一个地方是~/.pam_environment,如果您希望将变量设置为常量值(您不能在此文件中运行 shell 命令)。

设置环境变量的最佳发行版/与 shell 无关的方法是什么?,登录 Shell 和非登录 Shell 之间的区别?是否有一个所有 shell 都能读取的“.bashrc”等效文件?有关 shell 启动文件的更多信息。

答案2

cron 通常使用 sh 而不是 bash 运行,它们具有不同的配置文件。

尝试在 bash 下运行单独的 cron,如果您有多个自定义环境变量,则可以始终在 cron 中使用 env>/file, source /file。

答案3

我解决了我的问题:

  • run $ 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
...

相关内容