使用bash进程替换sudo命令

时间:2012-12-02 18:35:44

标签: bash

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

例如,这是一个适用于我的非sudo命令:

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

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

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

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

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

达到我在这里要做的事情的适当技巧是什么? Eval,引用,sudo标志,sudoers文件mod,其他?

5 个答案:

答案 0 :(得分:6)

尝试在shell中执行此操作:

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

答案 1 :(得分:6)

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

答案 2 :(得分:3)

sudo bash  -c 'cat <(echo "installed.txt")'

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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

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

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

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