將函式和變數轉發到 sudo su - <user> <<EOF
我已經在 bash/ksh 中聲明了函式和變數,我需要將它們轉發到
sudo su - {user} << EOF
:#!/bin/bash log_f() { echo "LOG line: $@" } extVAR="yourName" sudo su - <user> << EOF intVAR=$(date) log_f ${intVAR} ${extVAR} EOF
sudo su -
,這是一種複雜的寫作方式sudo -i
,建構了一個原始的環境。這就是登錄外殼的意義所在。即使是普通的,也會sudo
從環境中刪除大多數變數。此外sudo
是一個外部命令;沒有辦法提升 shell 腳本本身的權限,只能執行sudo
具有額外權限的外部程序 ( ),這意味著父 shell 中定義的任何 shell 變數(即非導出變數)和函式在子殼。您可以通過不呼叫登錄 shell(
sudo bash
而不是sudo su -
orsudo -i
)並配置 sudo 讓這些變數通過(在文件中使用Defaults !env_reset
or )來傳遞環境變數。這對函式沒有幫助(儘管 bash 有函式導出工具,但 sudo 會阻止它)。Defaults env_keep=…``sudoers
在子 shell 中獲取函式的正常方法是在那裡定義它們。注意引用:如果你使用
<<EOF
here文件,here文件的內容首先被父shell擴展,擴展的結果成為子shell看到的腳本。也就是說,如果你寫sudo -u "$target_user" -i <<EOF echo "$(whoami)" EOF
這將顯示原始使用者的名稱,而不是目標使用者的名稱。為避免第一階段的擴展,請在
<<
操作符後引用 here 文件標記:sudo -u "$target_user" -i <<'EOF' echo "$(whoami)" EOF
因此,如果您不需要將數據從父 shell 傳遞到子 shell,則可以使用這裡引用的文件:
#!/bin/bash sudo -u "$target_user" -i <<'EOF' log_f() { echo "LOG line: $@" } intVAR=$(date) log_f "${intVAR}" EOF
雖然您可以使用此處未引用的文件標記將數據從父 shell 傳遞到子 shell,但這僅在數據不包含任何特殊字元時才有效。那是因為在像這樣的腳本中
sudo -u "$target_user" -i <<EOF echo "$(whoami)" EOF
的輸出
whoami
變成了一些 shell 程式碼,而不是字元串。例如,如果whoami
命令返回"; rm -rf /; "true
,則子 shell 將執行命令echo ""; rm -rf /; "true"
。如果您需要從父 shell 傳遞數據,一種簡單的方法是將其作為參數傳遞。顯式呼叫子 shell 並將位置參數傳遞給它:
#!/bin/bash extVAR="yourName" sudo -u "$target_user" -i sh _ "$extVAR" <<'EOF' log_f() { echo "LOG line: $@" } intVAR=$(date) log_f "${intVAR}" "${1}" EOF
如果要傳遞多個變數,則按名稱傳遞它們會更易讀。顯式呼叫
env
以設置子 shell 的環境變數。#!/bin/bash extVAR="yourName" sudo -u "$target_user" -i env extVAR="$extVAR" sh <<'EOF' log_f() { echo "LOG line: $@" } intVAR=$(date) log_f "${intVAR}" "${1}" EOF
請注意,如果您希望讀取
/etc/profile
目標使用者~/.profile
,則必須明確讀取它們,或者呼叫bash --login
而不是呼叫sh
.