在 Cron 作業中載入環境變數


概述

當 crontab 執行命令時,它不會從諸如 ~/.bashrc、~/.bash_profile 等檔案中讀取任何環境變數。因為 cron 從非互動式、非登入 shell 執行任務,所以它不需要互動式使用者。某些應用程式需要環境變數才能正常執行。

我們將討論從 crontab 載入環境變數的不同方法。

設定 BASH_ENV 變數

我們可以使用 BASH_ENV 變數為 shell 指令碼設定環境變數。我們設定它,以便當我們執行作業時,它們由 shell 指令碼執行。我們可以設定 shell,以便當我們開啟一個新的終端視窗時,可以獲得系統正確的設定。我們可以使用 BASH_ENV 執行任何 shell 命令,而無需知道它的確切名稱。

我們將在 crontab 檔案中新增一行,在執行指令碼之前執行 /etc/profile。

* * * * * BASH_ENV=/etc/profile /home/baeldung/print_envs.sh

請注意,此作業每分鐘執行一次。此外,讓我們編寫 /home/baeldung/print_envs.sh 指令碼,使用 printenv 將所有環境變數列印到臨時檔案:

#!/bin/bash
printenv > /tmp/print_envs_result
Now, after setting execution permission to the script with chmod +x /home/tpoint/print_envs.sh, we’ll wait one minute to see the result:
$ wc -l /tmp/print_envs_result
38 /tmp/print_envs_result
$ grep PS1= /tmp/print_envs_result
PS1=\u@\h:\w\$

我們可以看到 print_envs 指令碼載入了 38 個環境變數。例如,它載入了 PS1 值。

您還可以使用 BASH_ENV 執行自定義 shell 命令。我們可以用它來載入多個檔案或新增更多變數。讓我們建立一個名為 preload.sh 的 shell 檔案,它載入四個不同的檔案:/etc/profile、~/.bash_profile、~/.bashrc,並匯出另一個變數。

#!/bin/bash
. /etc/profile
. ~/.bash_profile
. ~/.bashrc
export LEARNING_FROM=tpoint

現在,我們將修改 crontab 檔案以使用 /home/tpoint/preload.sh:

* * * * * BASH_ENV=/home/tpoint/preload.sh /home/tpoint/print_envs.sh

等待一分鐘後,我們得到結果:

$ wc -l /tmp/print_envs_result
41 /tmp/print_envs_result
$ grep LEARNING_FROM /tmp/print_envs_result
LEARNING_FROM=tpoint

我們注意到現在有 41 個環境變數。我們還有一個名為 LEARNING_FROM 的變數,其預設值為“tpoint”。

使用 Bash 包裝作業

假設我們有這個 crontab 檔案:

* * * * * printenv > /tmp/print_envs_result

因為 printenv 不是 shell 指令碼,所以我們不能使用 BSH_ENV 來載入環境變數值。但是,我們可以使用 Bash 來包裝它。我們透過在命令前新增 bash -c 並將其括在雙引號中來做到這一點。

我們透過在作業前新增 bash -c 並將作業括在雙引號中來實現這一點。Bash 在從傳遞給指令碼的引數讀取命令時使用 -c 選項。

我們將向指令碼新增 bash -c,以便我們可以檢查環境變數 BASH_ENV。

* * * * * BASH_ENV=/etc/profile bash -c "printenv > /tmp/print_envs_result"

cron 執行作業後,我們可以看到 printenv 從 /etc/profile 載入了所有環境變數:

$ wc -l /tmp/print_envs_result
38 /tmp/print_envs_result
$ grep PS1= /tmp/print_envs_result
PS1=\u@\h:\w\$

如果需要,我們可以新增更多環境變數,或者我們可以建立另一個 shell 檔案來包含我們想要新增的檔案。現在,我們有兩個選擇。我們可以透過設定名為 BASH_ENV 的環境變數來載入更新後的指令碼。就像以前一樣。相反,讓我們將原始作業從其在 crontabs 檔案中的當前位置移動到新 shell 指令碼的末尾。

讓我們建立一個名為 /home/tpoint/wrap_printenvs.sh 的新 shell 指令碼:

#!/bin/bash
. /etc/profile
. ~/.bash_profile
. ~/.bashrc
export LEARNING_FROM=tpoint
 
#now, we run the original job
printenv > /tmp/print_envs_result

最後,我們將 crontab 檔案更改為執行新指令碼:

* * * * * /home/tpoint/wrap_printenv.sh

與上一節類似,我們可以在結果中看到環境變數:

$ wc -l /tmp/print_envs_result
41 /tmp/print_envs_result
$ grep LEARNING_FROM /tmp/print_envs_result
LEARNING_FROM=tpoint

使用登入 shell 執行作業

為了模擬執行 crontab 條目時的相同順序,我們可以使用直譯器(例如 bash)來執行指令碼。當 Bash 作為登入 shell 工作時,它會讀取諸如 ~/.bash_profile、~/.bash_login、/etc/profile 和 ~/.profile 等檔案。這樣,bash shell 將載入所有啟動指令碼,並從這些檔案中載入環境變數。我們應該以 bash -l -c 開頭,並確保將其括在雙引號中。當我們希望命令處於登入(或互動式)模式時,-l 引數至關重要。

讓我們從互動式 shell 執行上一節中的 printenv 命令。

* * * * * bash -l -c "printenv > /tmp/print_envs_result"

因為這仍然是非互動式終端,所以 bash 不會載入 ~/.bashrc 檔案。如果我們也使用 BASH_ENV,我們可以克服這個問題。

我們將使用它來載入 ~/.bashrc 和登入 shell。

* * * * * BASH_ENV=~/.bashrc bash -l -c "printenv > /tmp/print_envs_result"

現在我們需要讓 cron 執行指令碼,然後檢查是否設定了任何環境變數。

$ wc -l /tmp/print_envs_result
41 /tmp/print_envs_result

在 Crontab 檔案中設定每個變數

我們可以使用 name=variable 語法在執行命令之前設定變數。如果我們想使用多個變數,我們必須用空格分隔多個變數。

我們需要設定執行 print_envs 指令碼的環境變數:

* * * * * LEARNING_FROM=tpoint LANG=es_US /home/tpoint/print_envs.sh

一分鐘後,我們現在可以看到指令碼將這些值載入到頁面中:

$ grep -E 'LANG|LEARNING_FROM' /tmp/print_envs_result
LEARNING_FROM=tpoint
LANG=en_US

如果我們想設定很多變數,那麼我們會以非常長的一行程式碼結束。如果這樣做,cron 作業可能難以理解。

像 Fedora 和 Arch Linux 這樣的程式提供了 cron 的 cron 守護程式實現;使用這些實現,我們可以在 /etc/crontab 檔案中為所有作業(包括系統範圍的作業)定義環境變數。我們將每個環境變數一次寫在一行中,其中不包含任何作業。

我們將為所有作業型別定義 LEARNING_FROM 和 LANG:

LEARNING_FROM=tpoint
LANG=es_US
* * * * * /home/baeldung/print_envs.sh

正如我們所看到的,指令碼載入了這些變數:

$ grep -E 'LANG|LEARNING_FROM' /tmp/print_envs_result
LEARNING_FROM=baeldung
LANG=en_US

結論

我們查看了為 cron 作業設定環境變數值的各種方法。

我們之前探討了如何使用 $BASH_ENV 環境變數在作業開始之前執行指令碼。此設定允許我們包含來自其他來源的環境變數,例如 /etc/bashrc。

接下來,我們看到我們可以將一個作業包裝在另一個作業中,在執行原始作業之前設定和載入所有所需的環境變數。

我們現在已經學習瞭如何單獨設定環境變數值,並將它們直接寫入 crontabs 檔案。

更新於:2023年1月3日

5K+ 次瀏覽

啟動您的 職業生涯

透過完成課程獲得認證

開始
廣告
© . All rights reserved.