在操作Linux作業系統的時候,經常會使用「sudo」指令來讓某個指令臨時擁有root權限。可是有時候卻會遇到,明明直接在終端機輸入某個指令(不使用「sudo」)可以正常執行得到,但在相同指令前加上「sudo」之後就執行不到了的狀況。這是什麼原因造成的呢?該如何解決?



先來看看下圖這個例子吧!

linux-sudo-path

「adb」是Android SDK提供,用來連接實體Android裝置的工具,其「devices」子命令可以列出目前的裝置連接狀態。但如上圖所示,我們在成功啟動adb的守護行程(daemon)之後,「adb」提示沒有權限存取某個裝置。

於是乎我們打算以root權限來執行「adb」指令,所以在使用「kill-server」這個「adb」的子命令後,我們重新使用了「adb」的「devices」子命令,並同時加上「sudo」來提升權限。

然而,此時系統卻提示「adb: command not found」。嗯……然後我們再嘗試使用「adb」可執行檔的絕對路徑來執行「adb」,這回卻成功了。

所以為什麼會發生這樣的事呢?

/etc/sudoers設定檔

「/etc/sudoers」是「sudo」的主要設定檔。事實上在使用「sudo」指令的時候,原先的「PATH」環境變數並不會在使用「sudo」指令時被套用,而是取而代之地用「/etc/sudoers」設定檔中的「secure_path」這個項目的設定值作為「sudo」指令的「PATH」環境變數的值。

linux-sudo-path

也就是說,若要修改能夠直接被「sudo」執行到的指令(可執行檔),可以來編輯這個「/etc/sudoers」設定檔中的「secure_path」設定項目。

當然,我們也可以利用以下方式,在執行「sudo」指令時,臨時將其「PATH」環境變數的值取代掉:

sudo env "PATH=/path/to/folder" 要執行的指令

如果要直接以目前的「PATH」環境變數來作為「sudo」指令的「PATH」環境變數,指令可以這樣寫:

sudo env "PATH=$PATH" 要執行的指令

以上的「$PATH」會在shell執行「sudo」指令前,就被替換為目前「PATH」環境變數的值,所以不會是「/etc/sudoers」設定檔中「secure_path」的值。

linux-sudo-path