不久前,我正在安裝 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_check
、env_keep
和env_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 -c
or中其他方法。