為什麼 sudo 找不到普通用戶可以找到的命令?

為什麼 sudo 找不到普通用戶可以找到的命令?

不久前,我正在安裝 NPM,我注意到當我嘗試使用 sudo 運行他們的安裝 shell 腳本時,它拋出了一些找不到命令的錯誤。然而,當嘗試在沒有 sudo 的情況下運行相同的腳本時,一切都很順利。

我是一個新的linux用戶,但根據我的理解,sudo的權限和可見性是普通用戶的超集。

為什麼會發生這種情況?

答案1

據我了解,sudo 的權限和可見性是普通用戶的超集。

權限,是的,但不一定是可見性。應用程式的可見性由PATH環境變數控制

~$ printenv PATH
/home/vanadium/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/games

當輸入命令時,命令解釋器首先檢查它是否是內部命令,或者該命令是否與磁碟上的可執行檔的名稱相對應。然後系統搜尋列出的目錄,PATH直到找到名稱與命令相符的可執行檔。

正如您在範例中看到的,使用者可以在 中擁有其他私有目錄PATH,並且僅在該使用者發出命令時才進行搜尋。因此,是的,使用者帳戶可以具有與root使用者不同的可用命令,即管理員,即您使用該命令時所承擔的角色sudo

儘管如此,可執行檔案的權限最終決定了誰可以運行該檔案。如果權限允許,則始終可以透過在提示符號上提供完整路徑名來運行可執行文件,例如,/usr/bin/mount而不僅僅是文件名,mount.事實上,root只要設定了可執行位,就可以始終執行,即使僅對所有者而言。

答案2

假設您要執行腳本目錄中的一個檔案。你會運行:

myscript.sh

並且腳本運行良好。但是運行 sudo 後,您得到的錯誤是這樣的:

sudo: myscript.sh: file not found

每當使用 sudo 時,它都會使用 root 使用者的路徑。解決方案是這樣運行命令:

sudo ./myscript.sh

答案3

shell(bash 等)在普通使用者和 sudo 模式下使用不同的變數。只需按照以下過程驗證這一點:

# Plain user
printenv > env1
# Using sudo
sudo printenv > env2
# Comparison
diff env1 env2
# Alternative comparison using the GUI tool meld
meld env1 env2

如果未安裝meld,您可以輕鬆安裝它。這非常有用。

sudo apt-get update
sudo apt-get install meld

普通 user / sudo 變數的不同內容可以影響 shell 行為和腳本功能。

檔案存取權限也不同。

答案4

事實上,事情比這更複雜一些。中需要存在幾個定義/etc/sudoers

確定環境發生的情況的控制標誌sudo是:env_checkenv_keepenv_reset

sudoers 的手冊頁在「命令環境」部分對此做了很好的解釋:

$ man --pager="less -p '^\ *Command environment'" sudoers

在開箱即用的 Ubuntu 配置中,PATH將呼叫為其定義的標誌secure_path(預設為啟用)。該值用於取代PATH要啟動的用戶sudo,因為env_reset預設情況下也是啟用的:

$ man sudoers | egrep "^\ *secure_path" -A4 | sed 's/^ *//'

secure_path   If set, sudo will use this value in place of the user's PATH environment variable. This option can be used to reset the PATH to a known good
value that contains directories for system administrator commands such as /usr/sbin.

Users in the group specified by the exempt_group option are not affected by secure_path.  This option is not set by default.

(編輯:上面的最後一行是指exempt_group預設情況下未啟用,而不是secure_path

visudo您可以使用(建議)修改它或顯示它:

$ sudo grep secure_path /etc/sudoers
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

其他時候,這些命令是 bash 內建的(例如echo),並且不是可以在PATH變數中引用的可執行檔。這些時候你必須將一些值輸入到sudo bash -cor中其他方法

相關內容