[英]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.