12

我想使用 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 命令之前正在创建描述符(并执行进程替换)。

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

什么是适当的技术来实现我在这里尝试做的事情?评估,引用,sudo 标志,sudoers 文件 mod,其他?

4

5 回答 5

13

问题中描述的行为是由于sudo.

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

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

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

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

 Defaults closefrom_override

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

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

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

于 2016-09-17T17:11:33.463 回答
10

尝试在你的 shell 中这样做:

$ sudo bash -c 'cat <(echo "installed.txt for UID=$UID")'
installed.txt for UID=0
于 2012-12-02T18:52:00.380 回答
3
sudo bash  -c 'cat <(echo "installed.txt")'
于 2012-12-02T18:54:57.450 回答
1

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

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

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

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

由于 shell 注入、环境变量等,这不仅速度慢,而且风险很大。

于 2021-07-23T19:39:43.210 回答
0

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

于 2012-12-02T18:45:53.317 回答