![为什么 sudo -S 会阻止交互式 shell](https://linux22.com/image/130980/%E4%B8%BA%E4%BB%80%E4%B9%88%20sudo%20-S%20%E4%BC%9A%E9%98%BB%E6%AD%A2%E4%BA%A4%E4%BA%92%E5%BC%8F%20shell.png)
我正在尝试使用 sudo 切换到另一个用户,但是当我使用该-S
选项从 stdin 读取密码时,我又返回到原来的用户。
例如
内容~newuser/.profile
:
echo "Welcome to newuser's account"
使用 sudo 时不带-S
:
$ whoami
origuser
$ sudo -iu newuser
[sudo] password for origuser:
Welcome to newuser's account
$ whoami
newuser
但是当使用时-S
:
$ whoami
origuser
$ sudo -Siu newuser < password.txt
Welcome to newuser's account
$ whoami
origuser
因此,正如您所看到的,使用-S
会导致调用并解析 shell .profile
,但随后 shell 会返回到原始用户。
为什么是这样?
有可能解决这个问题吗?
答案1
对于sudo -Siu newuser < password.txt
,命令的标准输入sudo -Siu newuser
取自password.txt
。该-S
选项导致sudo
从标准输入读取密码,从而从password.txt
.但后续 shell 的标准输入仍保持重定向。
当输入被重定向到 shell 时(无论它是否以交互模式运行)并且到达输入末尾,shell 就会退出。这类似于运行脚本并使其到达文件末尾,或者按Ctrl+D使终端指示输入结束。
因此,您正在启动一个 shell,其输入是从文件重定向的,该文件的内容可能已经大部分被读取。它到达终点并退出。实际上,您的目标是让您启动的 shellsudo
从终端获取输入,而不是从该文件获取输入。
尽管您可能可以使用附加文件描述符和更多间接以及其他方法来解决此问题,我建议您首先将身份验证作为单独的步骤执行,在运行 shell 之前:
sudo -Sv < password.txt
完成后,您可以运行:
sudo -iu newuser
如果您在第一个命令之后不久运行第二个命令,那么您的时间戳仍然有效,并且您根本不需要输入密码。
sudo
请注意,当您使用with以指定用户身份运行命令时-u
,其工作方式与以 root 身份运行命令时的工作方式相同(通常不使用-u
)。它要求您输入的密码是你的密码,而不是目标用户的用户,这就是为什么仅执行身份验证的命令(使用-v
)没有提及其他用户。这是可能的配置sudo
为期望目标用户的密码,但人们在实践中很少这样做,而且您也没有提到它,所以我认为这不是您(和大多数其他读者)感兴趣的。
(当然,与从此类文件中读取密码相关的安全风险的常见警告仍然适用,程度与之前相同。)
答案2
当 shell 运行时其标准输入连接到终端以外的其他设备,它会从标准输入读取命令并执行它们,直到标准输入关闭。
当你跑步时
sudo -Siu newuser < password.txt
sudo
的标准输入读取自password.txt
;sudo
在启动 shell 之前不会改变这一点,因此 shell 也会从password.txt
.然后可能会发生两件事:如果sudo
需要密码,它会读取密码,并且 shell 将立即到达文件末尾(假设它不包含任何其他内容)并退出;否则,shell 将尝试解析密码并执行它...
我不确定是否有可靠的方法来解决这个问题,并且在任何情况下,双重处理意味着您可能不想这样做(除非您禁用了令牌)。你能在启动 shell 之前准备一个令牌,如中所述埃利亚·卡根的回答,如果您没有禁用令牌。