Исполняемый файл запускается без sudo, но не с sudo
Я установил xampp в моей системе в расположении /opt/lampp
, После этого я добавил местоположение php в переменную path, используя
export PATH=$PATH:/opt/lampp/bin
Поэтому, когда я бегу php -v
используя терминал, я получаю ожидаемый результат.
PHP 5.6.8 (cli) (built: Apr 20 2015 18:37:47)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
Но когда я бегу sudo php -v
Я получаю это:
sudo: php: command not found
Я не знаю, почему это происходит. Я делаю что-то не так при добавлении его в переменную пути?
Редактировать:
Этот вопрос не является дубликатом переменных окружения при запуске с "sudo", потому что в этом вопросе дзеты спрашивали, как передать произвольные переменные команде python. Они способны выполнить python
с помощью sudo
, но я не могу выполнить php
с помощью sudo
,
После этого ответа я добавил PATH в sudo
используя следующую команду:
sudo PATH=$PATH:/opt/lampp/bin php -v
но я получаю вывод, как и раньше:
sudo: php: command not found
После этого ответа я добавил -E
в sudo
, но я получаю тот же результат:
$ sudo -E php -v
sudo: php: command not found
1 ответ
Зачем sudo
не использует ваш путь
Причина sudo
игнорирует вашу переменную PATH в том, что она имеет свою собственную secure_path
и вполне решительно им воспользуюсь.
если ты sudo cat /etc/sudoers
или просто sudo grep secure /etc/sudoers
, вы увидите, что это за путь в вашей системе. У меня есть эта строка:
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
Цель sudo
"s secure_path
состоит в том, чтобы уменьшить вероятность того, что пользователь с sudo
Привилегия (случайно) запускает опасный код от имени пользователя root после изменения их пути, возможно, для включения локальных каталогов.
Можно избежать sudo
с использованием secure_path
в целом путем изменения /etc/sudoers
закомментировать эту строку, но это было бы плохой идеей, потому что она устраняет меру безопасности, и это также не нужно, потому что вы можете легко обойти ее различными предпочтительными способами.
Получение sudo
использовать свой путь
Переопределить secure_path
и сделать sudo
используйте ваш PATH, как определено в настоящий момент, как прокомментировал muru, вы можете использовать:
sudo env PATH="$PATH" command
Обратите внимание, что -E
флаг или просто присвоение переменной не работают (по крайней мере, в Ubuntu).
$ mkdir junk # create a test directory to add to PATH
$ echo "echo foo" > junk/useless # create a harmless program
$ chmod u+x junk/useless # make it executable
$ PATH="$PATH":~/junk # add directory to PATH
При добавлении в PATH используйте абсолютный путь (оболочка развернется ~
перед присвоением переменной). Мне не нужно export
(и это не помогает), потому что PATH уже экспортирован, и изменение его значения приведет к тому, что дочерние процессы также наследуют изменения.
$ useless
foo
$ sudo useless
sudo: useless: command not found
$ sudo -E useless
sudo: useless: command not found
Часто ожидается, что это будет работать... man sudo
говорит:
-E, --preserve-env
Indicates to the security policy that the user wishes to
preserve their existing environment variables.
Но это не работает. -E
флаг не влияет на secure_path
, что, возможно, ошибка.
$ sudo PATH="$PATH" useless
sudo: useless: command not found
Это не влияет sudo
собственная среда, настроенная в соответствии с политикой безопасности, настроенная /etc/sudoers
, Это включает env_reset
а также secure_path
по умолчанию в Ubuntu, что приводит к загрузке минимальной среды и установке PATH на все, что находится в secure_path
,
Если sudo
смогли найти команду под названием useless
в одном из его собственных каталогов пути и запустить его, он будет проходить PATH=$PATH
в его среду, как показано здесь. Но он не будет использовать данное значение PATH. Решение заключается в следующем:
$ sudo env PATH="$PATH" useless
foo
Этот обходной путь использует env
Команда для установки PATH. В отличие от sudo
, env
использует заданные переменные для установки среды, затем ищет аргумент команды и запускает команду с измененной средой. Как info (coreutils) env invocation
говорит:
Модификации для
PATH
вступить в силу до поиска команды.
Установка пути
Когда вы изменили переменную PATH, чтобы включить каталог /opt/lampp/bin
Вы использовали эту команду:
export PATH=$PATH:/opt/lampp/bin
Это будет эффективно для текущей оболочки и всех дочерних процессов текущей оболочки, таких как оболочки, вызываемые из этой оболочки. Когда вы вышли из этой оболочки и все ее дочерние элементы вышли, эта измененная переменная PATH была полностью забыта, и когда вы откроете новую оболочку, вы найдете старую переменную PATH, которая не включает /opt/lampp/bin
, По этой причине полная команда, предложенная Муру,
sudo env PATH="$PATH:/opt/lampp/bin" php -v
было бы необходимо, если бы вы еще не использовали оболочку, в которую вы уже добавили /opt/lampp/bin
,
Чтобы навсегда изменить путь, вам потребуется отредактировать некоторый файл конфигурации, который изменяет вашу пользовательскую среду или читается оболочками при запуске. Вы можете добавить строку, чтобы назначить переменные среды в вашем ~/.profile
, например:
PATH="$PATH:/opt/lampp/bin"
Затем, после выхода из системы и возврата (или запуска source ~/.profile
чтобы увидеть эффект сразу), вы всегда сможете запустить
php -v
или же
sudo env PATH="$PATH" php -v
без корректировки вашего PATH в первую очередь.
Менее громоздкие альтернативы
Более удобным обходным решением может быть создание символической ссылки на исполняемый файл в расположении, которое находится в secure_path
и путь по умолчанию, например:
sudo ln -s /opt/lampp/bin/php /usr/local/bin/php
Тогда вам не нужно будет делать ничего особенного при вызове команды с sudo
Кроме того, вам никогда не потребуется предпринимать какие-либо шаги для корректировки вашей PATH, постоянно или временно.
Если программа, которую вы устанавливаете, имеет имя, совпадающее с именем другой программы, которую системные процессы могут пытаться вызывать, тогда дайте символической ссылке другое имя, чтобы избежать путаницы в этих процессах. Вы можете проверить, что имя, которое вы хотите использовать, уже не является именем какой-либо другой команды, используя type
команда:
$ type php
bash: type: php: not found
Так что в этой системе я могу создать команду php
без страха, что что-то пойдет не так, в данный момент. Если я установлю другие программы, которые предоставляют php
команда в будущем, возможно, придется пересмотреть мою конфигурацию.
Вы также можете сделать псевдоним для команды и добавить его в свой ~/.bashrc
, например:
alias sudo-php='sudo env PATH="$PATH:/opt/lampp/bin/php"'
Вы могли бы тогда (после запуска source .bashrc
или открытие новой оболочки) запустите
sudo-php
вместо sudo php
запустить эту программу от имени пользователя root и sudo
не будет утверждать, что не знает о его местонахождении.
Этот псевдоним будет доступен только в интерактивных оболочках, поэтому он не будет путать другие программы.
Конечно, можно сделать псевдоним только для sudo
чтобы всегда использовать ваш путь, с alias sudo='sudo env PATH="$PATH"'
, но это плохая идея, так как это сделает систему менее безопасной.