Команда не знайдена під час використання sudo


146

У мене в foo.shдомашній папці є сценарій .

Коли я переходжу до цієї папки та входжу ./foo.sh, я отримую

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

Коли я використовую sudo ./foo.sh, я отримую

sudo: foo.sh: command not found.

Чому це відбувається і як я можу це виправити?

Відповіді:


151

У дозволі відмовлено

Для запуску сценарію у файлі повинен бути встановлений біт дозволу, який можна виконати .

Щоб повністю зрозуміти дозволи файлів Linux, ви можете вивчити документацію для chmodкоманди. chmod , абревіатура зміни режиму , - це команда, яка використовується для зміни налаштувань дозволу для файлу.

Щоб прочитати документацію chmod для вашої локальної системи, запустіть man chmodабо info 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 в Command не знайдено

Коли ви запускаєте команду за допомогою sudo, ви ефективно виконуєте її як суперпользователь або root.

Причина того, що користувач root не знаходить вашу команду, ймовірно, що PATHзмінна середовища для root не включає каталог, де foo.shвін знаходиться . Отже команда не знайдена.

Змінна середовища PATH містить перелік каталогів, в яких здійснюється пошук команд. Кожен користувач встановлює власну змінну PATH відповідно до своїх потреб. Щоб побачити, що він налаштований для запуску

env | grep ^PATH

Ось деякий зразок результату виконання вищевказаної envкоманди спочатку як звичайний користувач, а потім як кореневий користувач, що використовує 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

Зауважте, що, хоч і схоже, в цьому випадку каталоги, що містяться в PATH, непривілейований користувач (rkielty) і суперкористувач не є однаковими .

Каталог, де foo.shзнаходиться резидент, не присутній у змінній PATH кореневого користувача, отже, в команді не знайдено помилки.


1
@Nakilon, якщо ви поставите це у запитанні з усіма детальними відомостями, я маю змогу вирішити це для вас далі. Ймовірно, питання про те, яка оболонка (ваша перша командна оболонка або оболонка, запущена sudo) оцінила $ PWD
Rob Kielty

6
@Rob: так як же роблять sudo«S PATHтакий же , як користувача?
Том

1
@Rob: Тим часом я знайшов спосіб (див. Мою відповідь нижче).
Том

1
Мені подобається, як ти пояснив! Дякую :)
Kasparov92

1
@Тому ви можете змінити безпечний шлях у / etc / sudoers
DennisLi

98

Інші рішення, які я бачив тут до цього часу, базуються на деяких системних визначеннях, але насправді можливо sudoвикористовувати поточне PATH(за допомогою envкоманди) та / або інше середовище (з -Eопцією), просто викликавши його правильно :

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

Насправді з нього можна зробити псевдонім:

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

(Можна також назвати сам псевдонім sudo, замінивши оригінал sudo.)


3
Мені подобається це рішення, Томе, бо ти свідомо працюєш із іншим викликом судо. Важливо пам’ятати про те, яка змінна PATH використовується у будь-який час будь-яким способом (а їх існує багато).
Роб Кільті

4
Я вважаю, що це правильне і найбільш стандартизоване рішення для command not foundпроблеми, з якою стикаються в дистрибутиві Ubuntu. Спасибі людина.
Омар Тарік

ви можете додати псевдонім до свого, ./bashrcщоб зберегти його між сеансами
Джордж

19

Перевірте наявність захисного шляху на sudo

[root@host ~]# 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

Дякую! Це допомогло розгадати таємницю судо-неможливості виконувати команди.
Євгеній Голдін

7
  1. Перевірте, чи у вас є дозвіл на виконання сценарію. тобтоchmod +x foo.sh
  2. Перевірте, чи є перший рядок цього сценарію #!/bin/shчи якийсь такий.
  3. Для судо ви потрапили в неправильний каталог. перевіритиsudo pwd

5

Ви також можете створити м'яке посилання на свій скрипт в одному з каталогів ( /usr/local/binнаприклад) у суперкористувацькій PATH. Тоді це буде доступне для судо.

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

Подивіться на цю відповідь, щоб мати уявлення про те, до якого каталогу розмістити м'яке посилання.


2

Здається, що Linux скаже "команда не знайдена", навіть якщо ви явно дасте шлях до файлу.

[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

Це дещо оманлива помилка, проте, ймовірно, технічно правильна. Файл не є командою до його виконання, тому його неможливо знайти.


1

Гаразд це моє рішення: у ~ / .bash_aliases просто додати наступне:

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

Вуаля! Тепер ви можете виконувати свої власні сценарії з sudo або встановлювати як ROOT без необхідності робити експорт PATH = $ PATH: / home / your_user / bin кожного разу.

Зверніть увагу, що я повинен бути явним, додаючи свій PATH, оскільки HOME для суперпользователя є / root


1

Спробуйте chmod u+x foo.shзамість того, chmod +x foo.shякщо у вас виникли проблеми з наведеними вище посібниками. Це працювало для мене, коли інших рішень не було.


1

Вище є чудові відповіді. Якщо, спробувавши їх, ви все-таки command not foundспробуйте повторити весь шлях до файлу:

sudo /home/user/path/to/foo.sh
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.