當我從 ( ) cronjob 呼叫腳本時,root
它失敗並顯示訊息「ipset not found」。這是有問題的腳本行:
for i in $(cat /etc/cn.zone); do ipset -A china $i; done
腳本中呼叫此命令之前的一些行:
ipset -N china hash:net
所以所討論的 ipset 實際上已經創建了。
如果我從 root 的主目錄執行此腳本,它將完美地運行。
知道什麼可能導致錯誤嗎?
答案1
當作為 cron 作業執行時,您的腳本看不到您的環境變數。
我從 () cronjob 呼叫一個腳本
root
,但它失敗並顯示訊息“ipset not found”...
您是否將此腳本作為 Bash 腳本運行?現在大多數 shell 腳本是什麼?
如果是這樣,那麼將腳本的第一行從
#!/bin/bash
對此:
#!/bin/bash -l
新增-l
告訴 Bash 運行就像它是作為登入 shell 呼叫一樣。如果 Bash 腳本透過該 cron 作業中的登入 shell 運行,則通常透過登入 shell 設定的所有環境變數(以及其他項目)將可供該 Bash 腳本使用,從而允許ipset
按預期運行。
which
您可以做的另一個技巧是在 Bash 變數中使用,如下所示;你顯然正在使用它,$(cat /etc/cn.zone)
所以機制是相似的:
$(which ipset)
並在你的腳本中將你的行更改為:
for i in $(cat /etc/cn.zone); do $(which ipset) -A china $i; done
這樣做的目的是 - 透過使用which
- 為您的腳本提供完整路徑ipset
(類似於/sbin/ipset
),無論您在哪個系統上運行該腳本。然後透過將其設定為解析變數$()
將讓腳本本身運行它。
ipset
但由於您在腳本中的其他地方使用,我建議(如果您使用此which
方法)重構腳本,將其設定ipset
為靠近腳本頂部的變數:
ipset_bin=$(which ipset);
然後像這樣呼叫你的命令:
$ipset_bin -N china hash:net
和這個:
for i in $(cat /etc/cn.zone); do $ipset_bin -A china $i; done
答案2
您的 shell 知道在哪裡可以找到可執行文件,例如ipset
透過查看您的PATH
,它是由您的環境設定的,但cron
不共享相同的環境。
將其添加到(或您的腳本)的頂部crontab
應該告訴它在哪裡可以找到您期望的命令:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin