Nie znaleziono polecenia podczas używania sudo

146

Mam skrypt wywołany foo.shw moim katalogu domowym.

Kiedy przechodzę do tego folderu i wchodzę ./foo.sh, otrzymuję

-bash: ./foo.sh: Permission denied.

Kiedy używam sudo ./foo.sh, dostaję

sudo: foo.sh: command not found.

Dlaczego tak się dzieje i jak mogę to naprawić?

Neko
źródło

Odpowiedzi:

151

Odmowa pozwolenia

Aby uruchomić skrypt, plik musi mieć ustawiony wykonywalny bit uprawnień .

Aby w pełni zrozumieć uprawnienia do plików w systemie Linux , możesz zapoznać się z dokumentacją chmodpolecenia. chmod , skrót od zmiany trybu , to polecenie używane do zmiany ustawień uprawnień pliku.

Aby przeczytać dokumentację chmod dla systemu lokalnego, uruchom man chmodlub info chmodz wiersza poleceń. Po przeczytaniu i zrozumieniu powinieneś być w stanie zrozumieć wynik działania ...

ls -l foo.sh

... która wyświetli uprawnienia do odczytu, zapisu i wykonania dla właściciela pliku, właściciela grupy i wszystkich innych, którzy nie są właścicielem pliku lub członkiem grupy, do której należy plik (ta ostatnia grupa uprawnień jest czasami nazywana jako „świat” lub „inny”)

Oto podsumowanie sposobów rozwiązywania problemów z błędem odmowy uprawnień w Twoim przypadku.

$ 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 

Właściciel ma prawa odczytu i zapisu rw, ale - wskazuje, że brakuje uprawnienia do pliku wykonywalnego

Te chmodpoprawki Polecenie to. (Grupa i inne mają tylko uprawnienia do odczytu pliku, nie mogą do niego pisać ani go wykonywać)

$ 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
   ^  ^  ^

Jeśli chodzi o Linuksa, foo.sh jest teraz wykonywalny.

Korzystanie z wyników sudo w poleceniu nie znaleziono

Kiedy uruchamiasz polecenie za pomocą sudo , skutecznie uruchamiasz je jako superużytkownik lub root.

Przyczyną, dla której użytkownik root nie może znaleźć polecenia, jest prawdopodobnie to, że PATHzmienna środowiskowa dla użytkownika root nie zawiera katalogu, w którym foo.shsię znajduje . Dlatego polecenie nie zostało znalezione.

Zmienna środowiskowa PATH zawiera listę katalogów, w których wyszukiwane są polecenia. Każdy użytkownik ustawia własną zmienną PATH zgodnie ze swoimi potrzebami. Aby zobaczyć, co ma działać

env | grep ^PATH

Oto przykładowe wyniki uruchomienia powyższego envpolecenia najpierw jako zwykły użytkownik, a następnie jako użytkownik root za pomocą sudo

rkielty@rkielty-laptop:~$ env | grep ^PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

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

Zauważ, że chociaż podobne, w tym przypadku katalogi zawarte w PATH dla nieuprzywilejowanego użytkownika (rkielty) i superużytkownika nietym samym .

Katalog, w którym foo.shrezyduje, nie jest obecny w zmiennej PATH użytkownika root, dlatego polecenie nie zostało znalezione .

Rob Kielty
źródło
1
@Nakilon, jeśli umieścisz to w pytaniu z pełnymi szczegółami, powinienem być w stanie rozwiązać ten problem dalej. Problem jest prawdopodobny, która powłoka (twoja pierwsza powłoka poleceń lub powłoka uruchomiona przez sudo) oceniła $ PWD
Rob Kielty
6
@Rob: więc jak sprawić sudo, by był PATHtaki sam jak użytkownik?
Tom
1
@Rob: W międzyczasie znalazłem sposób (zobacz moją odpowiedź poniżej).
Tom
1
Podoba mi się sposób, w jaki wyjaśniłeś! Dzięki :)
Kasparov92
1
@Tom możesz zmienić bezpieczną ścieżkę w / etc / sudoers
DennisLi
98

Inne rozwiązania, które tu widziałem, opierają się na niektórych definicjach systemowych, ale w rzeczywistości możliwe jest sudoużycie bieżącego PATH(za pomocą envpolecenia) i / lub reszty środowiska (z -Eopcją) po prostu wywołując je prawidłowo :

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

W rzeczywistości można z tego zrobić alias:

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

(Możliwe jest również nazwanie samego aliasu sudo, zastępując oryginał sudo).

Tomek
źródło
3
Podoba mi się to rozwiązanie, Tom, ponieważ świadomie pracujesz z innym wywołaniem sudo. Ważne jest, aby pamiętać o tym, jaka zmienna PATH jest używana przez cały czas, niezależnie od konfiguracji (a jest ich wiele).
Rob Kielty
4
Uważam, że jest to poprawne i najbardziej znormalizowane rozwiązanie command not foundproblemów występujących w dystrybucji Ubuntu. Dzięki.
Omar Tariq
możesz dodać alias do swojego, ./bashrcaby zapisać go między sesjami
George
19

Sprawdź secure_path w sudo

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

Jeśli $PATHjest zastępowany, użyj visudoi edytuj/etc/sudoers

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
codemonkee
źródło
Dzięki! Pomogło to rozwiązać zagadkę, że sudo nie może wykonywać poleceń.
Evgeny Goldin
7
  1. Sprawdź, czy masz uprawnienia do wykonywania skryptu. to znaczychmod +x foo.sh
  2. Sprawdź, czy pierwsza linia tego skryptu jest #!/bin/shlub coś takiego.
  3. W przypadku sudo jesteś w złym katalogu. Sprawdź zsudo pwd
Ed Heal
źródło
5

Możesz również utworzyć miękki link do swojego skryptu w jednym z katalogów ( /usr/local/binna przykład) w superużytkowniku PATH. Będzie wtedy dostępny dla sudo.

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

Spójrz na tę odpowiedź, aby mieć pojęcie, w którym katalogu umieścić miękki link.

TrigonaMinima
źródło
2

Wygląda na to, że linux powie „polecenie nie znaleziono”, nawet jeśli wyraźnie podasz ścieżkę do pliku.

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

Jest to nieco mylący błąd, ale prawdopodobnie technicznie poprawny. Plik nie jest poleceniem, dopóki nie jest wykonywalny, więc nie można go znaleźć.

Jeff MacDonald
źródło
1

Ok, to jest moje rozwiązanie: w ~ / .bash_aliases po prostu dodaj:

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

Voila! Teraz możesz wykonywać własne skrypty za pomocą sudo lub ustawić jako ROOT bez konieczności wykonywania eksportu PATH = $ PATH: / home / your_user / bin za każdym razem.

Zauważ, że muszę być wyraźny podczas dodawania mojej PATH, ponieważ HOME dla superużytkownika to / root

Fernando D Jaime
źródło
1

Spróbuj chmod u+x foo.shzamiast tego, chmod +x foo.shjeśli masz problemy z powyższymi przewodnikami. To zadziałało dla mnie, gdy inne rozwiązania nie.

Co znajduje się w wyszukiwarce Google
źródło
1

Powyżej znajdują się doskonałe odpowiedzi. Jeśli po ich wypróbowaniu nadal możesz command not foundspróbować ponownie z całą ścieżką pliku:

sudo /home/user/path/to/foo.sh
IggyM
źródło