可执行文件无需 sudo 运行,但使用 sudo 则不运行

Mah*_*rai 3 php sudo xampp environment-variables

我在我的系统中安装了 xampp 的位置/opt/lampp。之后我使用以下命令将 php 位置添加到我的路径变量中

export PATH=$PATH:/opt/lampp/bin
Run Code Online (Sandbox Code Playgroud)

因此,当我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
Run Code Online (Sandbox Code Playgroud)

但是当我跑步时sudo php -v我得到这个:

sudo: php: command not found
Run Code Online (Sandbox Code Playgroud)

我不知道为什么会发生这种情况。将其添加到路径变量时我做错了什么吗?

编辑:

这个问题不是与 'sudo' 一起运行时的环境变量的重复,因为在该问题中 zetah 询问如何将任意变量传递给 python 命令。他们能够执行pythonusing sudo,但我无法执行phpusing sudo

根据此答案sudo,我使用以下命令添加了 PATH :

sudo PATH=$PATH:/opt/lampp/bin php -v
Run Code Online (Sandbox Code Playgroud)

但我得到的输出和以前一样:

sudo: php: command not found
Run Code Online (Sandbox Code Playgroud)

按照这个答案,我添加-Esudo,但我得到了相同的结果:

$ sudo -E php -v
sudo: php: command not found
Run Code Online (Sandbox Code Playgroud)

Zan*_*nna 5

为什么sudo不使用你的路径

忽略您的 PATH 变量的原因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"
Run Code Online (Sandbox Code Playgroud)

sudo的目的secure_path是尽量减少具有sudo特权的用户在其路径被修改后(可能包括本地目录)以 root 身份(意外地)运行危险代码的可能性。

可以通过修改以注释掉该行来完全避免sudo使用,但这将是一个坏主意,因为它删除了安全措施,而且它也是不必要的,因为您可以轻松地以各种更好的方式解决它。secure_path/etc/sudoers

开始sudo使用你的 PATH

要覆盖secure_pathsudo使用当前定义的 PATH,如 muru 评论的那样,您可以使用:

Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
Run Code Online (Sandbox Code Playgroud)

请注意,该-E标志或仅分配变量不起作用(至少在 Ubuntu 上)。

sudo env PATH="$PATH" command
Run Code Online (Sandbox Code Playgroud)

添加到 PATH 时,请使用绝对路径(shell 将~在分配变量之前展开)。我不需要export(这样做没有帮助),因为 PATH 已经导出,并且更改其值将导致子进程也继承更改。

$ 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
Run Code Online (Sandbox Code Playgroud)

人们通常期望这会起作用......man sudo说:

$ useless
foo
$ sudo useless
sudo: useless: command not found
$ sudo -E useless
sudo: useless: command not found
Run Code Online (Sandbox Code Playgroud)

但这是行不通的。该-E标志对 没有影响secure_path这可能是一个错误

-E, --preserve-env
            Indicates to the security policy that the user wishes to
            preserve their existing environment variables.
Run Code Online (Sandbox Code Playgroud)

这不会影响sudo自己的环境,该环境已经根据配置的安全策略设置/etc/sudoers。这包括env_resetUbuntusecure_path上的默认设置,导致加载最小环境并将 PATH 设置为secure_path.

如果sudo能够找到useless在其自己的路径目录之一中调用的命令并运行它,它将传递PATH=$PATH到其环境中,如此处所示。但它本身不会使用给定的 PATH 值。解决方案是运行:

$ sudo PATH="$PATH" useless
sudo: useless: command not found
Run Code Online (Sandbox Code Playgroud)

此解决方法使用env命令来设置 PATH。与 不同的是sudoenv使用给定的变量来设置环境,然后查找命令参数并使用修改后的环境运行命令。正如info (coreutils) env invocation所说:

修改PATH在搜索command之前生效。

设置路径

当您更改 PATH 变量以包含该目录时/opt/lampp/bin,您使用了以下命令:

$ sudo env PATH="$PATH" useless
foo
Run Code Online (Sandbox Code Playgroud)

这对于当前 shell 和当前 shell 的所有子进程(例如从此 shell 调用的 shell)都有效。当您退出此 shell 及其所有子 shell 时,修改后的 PATH 变量已被彻底遗忘,当您打开新 shell 时,您会发现旧的 PATH 变量不包含/opt/lampp/bin. 因此,muru 建议的完整命令,

export PATH=$PATH:/opt/lampp/bin
Run Code Online (Sandbox Code Playgroud)

如果您不再使用已经添加了/opt/lampp/bin.

要永久更改路径,您需要编辑一些配置文件来修改您的用户环境或在 shell 启动时读取这些配置文件。您可以添加一行来在您的 中分配环境变量~/.profile,例如:

sudo env PATH="$PATH:/opt/lampp/bin" php -v
Run Code Online (Sandbox Code Playgroud)

然后,注销并重新登录(或source ~/.profile立即运行以查看效果)后,您将始终能够运行

PATH="$PATH:/opt/lampp/bin"
Run Code Online (Sandbox Code Playgroud)

或者

php -v
Run Code Online (Sandbox Code Playgroud)

无需先调整您的路径。

不那么麻烦的替代方案

更方便的解决方法可能是在默认路径中的位置创建指向可执行文件的符号链接secure_path,例如:

sudo env PATH="$PATH" php -v
Run Code Online (Sandbox Code Playgroud)

然后,在使用 调用命令时,您不需要执行任何特殊操作sudo,也不需要采取任何步骤来永久或临时调整您的 PATH。

如果您正在安装的程序的名称与系统进程可能尝试调用的另一个程序的名称相同,则为符号链接指定一个不同的名称,以避免混淆这些进程。您可以使用以下命令检查要使用的名称是否已经不是其他命令的名称type

sudo ln -s /opt/lampp/bin/php /usr/local/bin/php
Run Code Online (Sandbox Code Playgroud)

php因此,在这个系统上,我现在可以创建一个命令,而不必担心出现任何问题。php如果我将来安装其他提供命令的程序,我可能必须重新考虑我的配置。

您还可以为该命令创建一个别名并将其添加到您的 中~/.bashrc,例如:

$ type php
bash: type: php: not found
Run Code Online (Sandbox Code Playgroud)

然后你可以(运行source .bashrc或打开一个新的外壳后)运行

alias sudo-php='sudo env PATH="$PATH:/opt/lampp/bin/php"'
Run Code Online (Sandbox Code Playgroud)

而不是以sudo phproot 身份运行该程序,并且sudo不会声称不知道其位置。

该别名仅在交互式 shell 中可用,因此不会混淆其他程序。

当然,可以创建一个别名,只是为了sudo让它始终使用您的 PATH,alias sudo='sudo env PATH="$PATH"'但这是一个坏主意,因为它会降低系统的安全性。


归档时间:

查看次数:

3718 次

最近记录:

8 年,2 月 前