Почему sudo не может найти команду, которую может найти обычный пользователь?

Почему sudo не может найти команду, которую может найти обычный пользователь?

Некоторое время назад я устанавливал NPM и заметил, что когда я пытался запустить их скрипт установки оболочки с помощью sudo, он выдавал ошибки о том, что некоторые команды не были найдены. Однако при попытке запустить тот же скрипт без sudo все работало как часы.

Я новый пользователь Linux, но, насколько я понимаю, права доступа и видимость sudo являются расширенным набором прав обычного пользователя.

Почему это происходит?

решение1

Насколько я понимаю, права доступа и видимость sudo являются расширенным набором прав обычного пользователя.

Разрешения, да, но не обязательно видимость. Видимость приложений регулируется PATHпеременной окружения

~$ printenv PATH
/home/vanadium/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/games

При вводе команды интерпретатор команд сначала проверяет, является ли она внутренней командой или соответствует ли команда имени исполняемого файла на диске. Затем система просматривает каталоги, перечисленные в , PATHпока не будет найден исполняемый файл с именем, соответствующим команде.

Как вы видите в примере, пользователь может иметь дополнительные личные каталоги в PATH, поиск по которым выполняется только тогда, когда этот пользователь вводит команду. Таким образом, да, учетная запись пользователя может иметь другие доступные команды, чем rootпользователь, т. е. администратор, роль, предполагаемая при использовании sudoкоманды.

Тем не менее, разрешения исполняемого файла в конечном итоге определяют, кто может запустить файл. При условии, что разрешения это позволяют, исполняемый файл всегда можно запустить, указав полный путь в приглашении, например, /usr/bin/mountвместо просто имени файла, mount. И действительно, rootвсегда можно выполнить, пока установлен бит исполняемости, даже если это так только для владельца.

решение2

Допустим, вы хотите запустить файл в вашем каталоге scripts. Для этого вам нужно выполнить:

myscript.sh

и скрипт работает нормально. Но после запуска sudo вы получаете такую ​​ошибку:

sudo: myscript.sh: file not found

Всякий раз, когда используется sudo, он использует путь пользователя root. Решением этой проблемы будет запуск команды таким образом:

sudo ./myscript.sh

решение3

Оболочка (bash и т. д.) использует разные переменные в обычном пользовательском режиме и режиме sudo. Просто проверьте это, выполнив следующую процедуру:

# Plain user
printenv > env1
# Using sudo
sudo printenv > env2
# Comparison
diff env1 env2
# Alternative comparison using the GUI tool meld
meld env1 env2

Если meld не установлен, вы можете легко установить его. Он очень полезен.

sudo apt-get update
sudo apt-get install meld

Различное содержимое переменных обычного пользователя / sudo может влиять на поведение оболочки и функциональность скрипта.

Разрешения на доступ к файлам также различаются.

решение4

На самом деле, все немного сложнее. Есть пара определений, которые должны существовать в /etc/sudoers.

Управляющие флаги, определяющие, что происходит с sudoокружающей средой: env_check, env_keep, и env_reset.

Theman-страница для sudoersхорошо объясняет это в разделе «Командная среда»:

$ man --pager="less -p '^\ *Command environment'" sudoers

В стандартной конфигурации Ubuntu флаг, который определен для PATHназывается secure_path(включен по умолчанию). Значение используется вместо пользователя PATHдля запуска, sudoпоскольку env_resetтакже включен по умолчанию:

$ man sudoers | egrep "^\ *secure_path" -A4 | sed 's/^ *//'

secure_path   If set, sudo will use this value in place of the user's PATH environment variable. This option can be used to reset the PATH to a known good
value that contains directories for system administrator commands such as /usr/sbin.

Users in the group specified by the exempt_group option are not affected by secure_path.  This option is not set by default.

(Изменить: последняя строка выше относится к тому, что exempt_groupне включено по умолчанию, а не к secure_path)

Вы можете изменить его с помощью visudo(рекомендуется) или отобразить его:

$ sudo grep secure_path /etc/sudoers
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

В других случаях команды встроены в bash (например echo, ) и не являются исполняемым файлом, на который можно ссылаться в PATHпеременной. Это те случаи, когда вам нужно передать некоторое значение в sudo bash -cилидругие способы.

Связанный контент