不久前,我正在安装 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_check
、env_keep
和env_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
或其他方法。