波浪號擴展與 Bash 中的變數
請考慮以下程式碼段:
$ export xx=foo $ sudo bash -c 'echo $xx ~' /root
沒關係。我們看不到xx。
但是,如果我公開它:
$ sudo -E bash -c 'echo $xx ~' foo /home/xropi
雖然很多人說*~不是別名,但不知何故它是環境的一部分,因為-E*會暴露原件,阻止我推遲評估。
是否可以在 sudo-ed 命令中傳遞我的變數並評估 ~ 作為 /root ?
我想在使用 sudo 執行時得到這個:
foo /root
您對波浪號如何工作的理解是不完整的。查看
man bash
並蒐索Tilde Expansion
。它以(我添加的額外換行符和一些粗體)開頭:
如果單詞以不帶引號的波浪號字元 (
~
) 開頭,則第一個不帶引號的斜杠之前的所有字元(或所有字元,如果沒有不帶引號的斜杠)都被視為波浪號前綴。如果波浪號前綴中沒有任何字元被引用,波浪號後面的波浪號前綴中的字元將被視為可能的登錄名。
如果此登錄名是空字元串,波浪號將替換為 shell 參數的值
HOME
。 如果HOME
未設置,則替換執行 shell 的使用者的主目錄。否則,波浪號前綴將替換為與指定登錄名關聯的主目錄。
簡而言之,
~
擴展為 $ HOME, if $ HOME 非空。
sudo
在沒有 . 的情況下執行時不保留使用者的環境變數(包括$HOME
)-E
。,-E
它確實如此。順便說一句,同樣值得注意的是:雖然大多數 shell 可以並且確實可以擴展
~
為使用者的主目錄,但並非所有程序都可以。事實上,大多數程序都沒有——這不是他們真正的工作,他們依靠 shell在看到任何參數之前執行波浪號和變數以及 glob 和其他擴展。問題:是否可以在 sudo-ed 命令中傳遞我的變數並評估 ~ 作為 /root ?
有幾種方法,每種方法都有優點和缺點。這裡是其中的一些:
unset HOME
在執行之前sudo -E
。HOME=/root
執行前設置sudo -E
。例如HOME=/root sudo -E bash -c 'echo $xx ~'
- 將要與 sudo 共享的變數寫入文件。例如,您可以執行
declare -p var1 var2 var3 > /tmp/myvars.sh
並讓sudo
(不-E
)執行一個 shell 腳本,該腳本source /tmp/myvars.sh
在執行您想要執行的任何內容之前執行sudo
。- 使用or中的
env_keep
設置- 這允許您定義在執行時將始終保留哪些變數,無論是否使用該選項。/etc/sudoers``/etc/sudoers.d/*``sudo``-E
- (來自@MichaelHomer)使用
sudo
’-H
選項將 HOME 設置為目標使用者的主目錄並--preserve-env=xx
告訴 sudo 傳遞xx
變數(此選項採用逗號分隔的環境變數名稱列表)。詳情請參閱man sudo
。請注意,並非所有使用者都有權保護環境。見man sudoers
。
sudo
請注意,預設情況下不保留環境變數是有充分理由的。有許多 env vars 具有嚴重的安全隱患,並且濫用可能允許使用者或組獲得對他們不應訪問的事物的 root(或其他 uid)訪問權限。