当我 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
...