为什么 sudo 找不到普通用户可以执行的命令?

为什么 sudo 找不到普通用户可以执行的命令?

不久前,我正在安装 NPM,我注意到当我尝试使用 sudo 运行其安装 shell 脚本时,它会抛出一些未找到命令的错误。然而,当我尝试在没有 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

假设您想要运行目录脚本中的文件。您可以运行:

myscript.sh

脚本运行正常。但是在运行 sudo 之后,您收到以下错误:

sudo: myscript.sh: file not found

每当使用 sudo 时,它都会使用 root 用户的路径。解决方案是按如下方式运行命令:

sudo ./myscript.sh

答案3

shell(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 变量的不同内容会影响 shell 行为和脚本功能。

文件的访问权限也不同。

答案4

事实上,情况比这要复杂一些。 中需要存在几个定义/etc/sudoers

决定环境发生什么情况的控制标志sudo是:env_checkenv_keepenv_reset

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其他方法

相关内容