讓 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
...

相關內容