繁体   English   中英

使用 bash 进程替换 sudo 命令

[英]Using bash process substitution for a sudo command

我想对 sudo 命令使用 bash 进程替换。

例如,这是一个对我有用的非 sudo 命令:

$ cat <(echo "installed.txt")
installed.txt

这是一个不起作用的命令的 sudo 版本:

$ sudo cat <(echo "installed.txt")
cat: /dev/fd/63: Bad file descriptor

阅读 sudo 手册页,似乎 sudo 在以 root 身份运行命令之前关闭了除 stdin/stdout/stderr 文件描述符之外的所有文件描述符。 这让我认为 bash 在运行 sudo 命令之前正在创建描述符(并执行进程替换)。

我将 root 的 shell 更改为 bash(而不是 sh 默认值)。 我已经测试过该命令在以 root 身份登录时可以正常工作。 它只是不能通过 sudo 命令工作。

实现我在这里要做的事情的适当技术是什么? Eval,引用,sudo 标志,sudoers 文件模块,其他?

问题中描述的行为是由于sudo的设计。

$ sudo cat <(echo "installed.txt")
cat: /dev/fd/63: Bad file descriptor

发生错误是因为sudo有一个默认行为,即关闭除标准输入、输出和错误之外的文件描述符。 如手册页所述:

默认情况下,sudo 会在执行命令时关闭除标准输入、标准输出和标准错误之外的所有打开的文件描述符。

此行为可以用-C (或--close-from )选项覆盖以指定文件描述符编号,低于该编号不应关闭文件。 但是,使用此选项必须得到管理员的允许:以下需要添加到/etc/sudoers

 Defaults closefrom_override

有了它,如果使用-C ,该命令将起作用:

$ sudo -C64 cat <(echo "installed.txt")
installed.txt

(这里给出了数字64 ,因为它大于错误消息中的63 )。

尝试在您的 shell 中执行此操作:

$ sudo bash -c 'cat <(echo "installed.txt for UID=$UID")'
installed.txt for UID=0
sudo bash  -c 'cat <(echo "installed.txt")'

最好的方法可能是将所有内容都放在一个脚本中,然后使用sudo运行该脚本。

如果您要求进程替换它带来的安全性,例如从进程列表中隐藏密码,那么您最好这样做:

cat <(echo -n "$PASSWORD") | sudo cryptsetup ... --key-file -

当然,密码是通过它的stdin发送到sudo ,所以进程替换不是按照要求sudo完成的。 我的回答在技术上变得离题了。

我仍然希望它在这个特定的上下文中有所帮助,因为接受的答案有严重的缺点:您需要构建一个正确引用的字符串,然后生成一个辅助 shell 以在sudo解释它。

这使得它不仅速度慢,而且由于 shell 注入、环境变量等原因而存在风险。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM