Bash

波浪號擴展與 Bash 中的變數

  • December 31, 2021

請考慮以下程式碼段:

$ 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 ?

有幾種方法,每種方法都有優點和缺點。這裡是其中的一些:

  1. unset HOME在執行之前sudo -E
  2. HOME=/root執行前設置sudo -E。例如HOME=/root sudo -E bash -c 'echo $xx ~'
  3. 將要與 sudo 共享的變數寫入文件。例如,您可以執行declare -p var1 var2 var3 > /tmp/myvars.sh並讓sudo(不-E)執行一個 shell 腳本,該腳本source /tmp/myvars.sh在執行您想要執行的任何內容之前執行sudo
  4. 使用or中的env_keep設置- 這允許您定義在執行時將始終保留哪些變數,無論是否使用該選項。/etc/sudoers``/etc/sudoers.d/*``sudo``-E
  5. (來自@MichaelHomer)使用sudo-H選項將 HOME 設置為目標使用者的主目錄並--preserve-env=xx告訴 sudo 傳遞xx變數(此選項採用逗號分隔的環境變數名稱列表)。詳情請參閱man sudo。請注意,並非所有使用者都有權保護環境。見man sudoers

sudo請注意,預設情況下不保留環境變數是有充分理由的。有許多 env vars 具有嚴重的安全隱患,並且濫用可能允許使用者或組獲得對他們不應訪問的事物的 root(或其他 uid)訪問權限。

引用自:https://unix.stackexchange.com/questions/684395