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



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

linux-sudo-path

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

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

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

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

/etc/sudoers設定檔

/etc/sudoerssudo的主要設定檔。事實上在使用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