我在系统中的以下位置安装了 xampp /opt/lampp
。之后,我使用以下方法将 php 位置添加到我的路径变量中:
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”运行时的环境变量,因为在那个问题中 zetah 询问如何将任意变量传递给 python 命令。他们可以使用 执行python
,sudo
但我无法使用php
执行sudo
。
下列的这个答案sudo
,我使用以下命令添加了 PATH :
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
不使用你的 PATH
忽略您的 PATH 变量的原因sudo
是它有自己的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
的目的secure_path
是尽量减少具有sudo
特权的用户在其路径被修改(可能包括本地目录)后(意外地)以 root 身份运行危险代码的可能性。
可以通过修改注释掉该行来完全避免sudo
使用,但这不是一个好主意,因为它会删除安全措施,而且也是不必要的,因为您可以通过各种可取的方式轻松解决它。secure_path
/etc/sudoers
使用sudo
你的 PATH
要覆盖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 时,请使用绝对路径(shell 将~
在分配变量之前进行扩展)。我不需要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
当您更改 PATH 变量以包含目录时/opt/lampp/bin
,您使用了以下命令:
export PATH=$PATH:/opt/lampp/bin
这将对当前 shell 及其所有子进程(例如从此 shell 调用的 shell)有效。当您退出此 shell 及其所有子进程时,修改后的 PATH 变量已被彻底遗忘,当您打开新 shell 时,您会发现旧的 PATH 变量不包含/opt/lampp/bin
。因此,完整命令muru 建议,
sudo env PATH="$PATH:/opt/lampp/bin" php -v
/opt/lampp/bin
如果你没有继续使用已经添加了 的 shell 的话,那么这将是必要的。
要永久更改路径,您需要编辑一些配置文件,该文件会修改您的用户环境或由 shell 在启动时读取。您可以在 中添加一行来分配环境变量~/.profile
,例如:
PATH="$PATH:/opt/lampp/bin"
然后,在注销并重新登录(或运行source ~/.profile
以立即查看效果)后,您将始终能够运行
php -v
或者
sudo env PATH="$PATH" php -v
无需先调整你的 PATH。
更简便的替代方案
一个更方便的解决方法是创建指向位于secure_path
默认 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
或打开新 shell 后)运行
sudo-php
而不是以sudo php
root 身份运行该程序,并且sudo
不会声称不知道它的位置。
此别名仅在交互式 shell 中可用,因此不会混淆其他程序。
当然,可以创建一个别名,以sudo
使其始终使用您的 PATH,alias sudo='sudo env PATH="$PATH"'
但这是一个坏主意,因为它会降低系统的安全性。