Исполняемый файл запускается без 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"', но это плохая идея, так как это сделает систему менее безопасной.

Другие вопросы по тегам