2012-10-21 81 views
105

我的主文件夾中有一個名爲foo.sh的腳本。使用sudo時未找到命令

當我瀏覽到該文件夾​​,並輸入./foo.sh,我得到

-bash: ./foo.sh: Permission denied

當我使用sudo ./foo.sh,我得到

sudo: foo.sh: command not found

爲什麼會發生這種情況,我該如何解決?

回答

114

權限檢查被拒絕

爲了運行一個腳本文件必須有可執行權限位設置

爲了充分理解Linux file permissions,您可以研究chmod命令的文檔。 chmod更改模式的縮寫,是用於更改文件權限設置的命令。

要讀取本地系統的chmod文檔,請從命令行運行man chmodinfo chmod。一旦閱讀和理解,你應該能夠理解運行的輸出...

ls -l foo.sh 

...這將列出讀,寫和執行權限的文件所有者,組所有者和其他人誰是不是文件所有者或文件所屬組的成員(最後一個許可組有時被稱爲「世界」或「其他」)

下面是如何排除權限被拒絕錯誤在你的情況。

$ ls -l foo.sh     # Check file permissions of foo 
-rw-r--r-- 1 rkielty users 0 2012-10-21 14:47 foo.sh 
    ^^^ 
^^^ | ^^^ ^^^^^^^ ^^^^^ 
    | | |  |  | 
Owner| World |  | 
    |   | Name of 
    Group  |  Group 
      Name of 
       Owner 

所有者擁有讀寫訪問RW但是 - 表示可執行權限丟失

chmod命令修復了。 (集團等只有讀權限在文件上設置,他們不能寫或執行它)

$ chmod +x foo.sh    # The owner can set the executable permission on foo.sh 
$ ls -l foo.sh     # Now we see an x after the rw 
-rwxr-xr-x 1 rkielty users 0 2012-10-21 14:47 foo.sh 
^^^

foo.sh現在是可執行的儘可能的Linux而言。在命令

使用sudo結果未發現

當你使用sudo的有效地運行它作爲超級用戶或root身份運行命令。

原因根用戶沒有找到您的命令可能是root的PATH環境變量不包括目錄下foo.sh位於。因此找不到命令。

PATH環境變量包含搜索命令的目錄列表。每個用戶根據自己的需要設置自己的PATH變量。 看看它設置爲運行

env | grep ^PATH 

下面是使用sudo

[email protected]:~$ env | grep ^PATH 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games 

[email protected]:~$ sudo env | grep ^PATH 
[sudo] password for rkielty: 
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin 

注意,第一次作爲一個普通用戶,然後運行上面env命令以root用戶的一些示例輸出,雖然類似,在這種情況下,PATH中包含的目錄非特權用戶(rkielty)和超級用戶不一樣

foo.sh所在的目錄不存在於root用戶的PATH變量中,因此命令未找到錯誤。

+0

奇怪的是,'sudo $ PWD/temp.sh'也不能正常工作,而'sudo echo $ PWD'則顯示我等待的內容。 (Mac) – Nakilon

+0

@Nakilon如果你把這個問題放在一個完整的細節問題中,我應該能夠爲你進一步排除故障。問題可能在於哪個shell(你的第一個命令shell或由sudo啓動的shell)已經評估了$ PWD –

+0

@RobKielty,沒關係。我不記得確切的問題,但可能是不喜歡在腳本中爲一個命令設置chmod -x,並且通過sudo調用腳本生成的不是那麼容易理解的錯誤消息。 – Nakilon

6
  1. 檢查您是否擁有該腳本的執行權限。即chmod +x foo.sh
  2. 檢查該腳本的第一行是否爲#!/bin/sh或其他。
  3. 對於sudo,您在錯誤的目錄中。與sudo pwd
7

檢查secure_path上須藤

[[email protected] ~]# sudo -V | grep 'Value to override' 
Value to override user's $PATH with: /sbin:/bin:/usr/sbin:/usr/bin 

如果$PATH是被重寫使用visudo和編輯/etc/sudoers

Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin 
+0

謝謝!這有助於解決sudo無法運行命令的謎團。 –

57

我在這裏看到的其他解決方案到目前爲止是基於一些系統上定義,但實際上可以讓sudo使用當前的PATH(使用env命令)和/或環境(與-E選項),其他人只是通過調用它的權利:

sudo -E env "PATH=$PATH" <command> [arguments] 

事實上,一個可以讓一個別名出來的:

alias mysudo='sudo -E env "PATH=$PATH"' 

(也有可能命名別名本身sudo,取代原來的sudo。)

+3

我喜歡這個解決方案,Tom,因爲你有意識地使用不同的sudo調用。注意PATH變量在任何時候都被使用(並且有很多),這一點很重要。 –

+2

我相信這是Ubuntu發行版面臨'command not found'問題的正確和最標準化的解決方案。謝啦。 –

1

看來,即使你明確地給出文件的路徑,linux會說「command not found」。

[[email protected] ~]$ sudo /tmp/uid.sh;echo $? 
sudo: /tmp/uid.sh: command not found 
1 
[[email protected] ~]$ chmod +x /tmp/uid.sh 
[[email protected] ~]$ sudo /tmp/uid.sh;echo $? 
0 

這是一個有點誤導性的錯誤,但它可能在技術上是正確的。一個文件直到它的可執行文件不是一個命令,所以不能被發現。

1

好的,這是我的解決方案: in〜/。bash_aliases只需添加以下內容:

# ADDS MY PATH WHEN SET AS ROOT 
if [ $(id -u) = "0" ]; then 
    export PATH=$PATH:/home/your_user/bin 
fi 

瞧! 現在,您可以使用sudo執行您自己的腳本,或者設置爲ROOT,而無需每次都執行export PATH = $ PATH:/ home/your_user/bin。

請注意,我需要從HOME超級用戶加入我的路徑時,要明確是/根

2

,您還可以在超級用戶創建一個目錄中(/usr/local/bin爲例)的軟鏈接腳本路徑。它隨後可供sudo使用。

chmod +x foo.sh 
sudo ln -s path-to-foo.sh /usr/local/bin/foo 

看一看this answer有一個想法,目錄中放置的軟鏈接。

0

嘗試chmod u+x foo.sh而不是chmod +x foo.sh如果你有以上的導遊麻煩。當其他解決方案沒有時,這對我有效。