使用 bash 进程替换 sudo 命令



我想用 bash 进程替换来代替 sudo 命令。

例如,这里有一个对我有用的非 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 命令之前正在创建描述符(并执行进程替换)。

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

实现我在这里尝试做的事情的适当技术是什么?Eval, 引用, sudo flag, sudoers file mod, 其他?

问题中描述的行为是由于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")'

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

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

当然,密码是通过其stdin发送给sudo的,因此该过程替换不会按照要求在sudo完成。我的回答在技术上变得跑题了。

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

这使得它不仅速度慢,而且由于外壳注入、环境变量等原因,它也有风险。

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

相关内容

  • 没有找到相关文章

最新更新