我已经在我们开发的一个RedHat linux机器上获得了sudo访问权,我似乎发现自己经常需要将输出重定向到一个我通常没有写访问权的位置。

问题是,这个人为的例子不起作用:

sudo ls -hal /root/ > /root/test.out

我刚刚收到回复:

-bash: /root/test.out: Permission denied

我怎样才能让它工作呢?


当前回答

这个主题还有另一个变体:

sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF

或者当然:

echo 'ls -hal /root/ > /root/test.out' | sudo bash

它们有一个(微小的)优势,即您不需要记住sudo或sh/bash的任何参数

其他回答

也许你只被授予sudo访问一些程序/路径?那就没办法做你想做的事了。(除非你能破解)

如果不是这样,那么也许你可以编写bash脚本:

cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out 

按ctrl + d:

chmod a+x myscript.sh
sudo myscript.sh

希望能有所帮助。

刚才有人建议sudo tee:

sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null

这也可以用于将任何命令重定向到您没有访问权限的目录。它之所以有效,是因为tee程序实际上是一个“回显到文件”程序,重定向到/dev/null是为了阻止它也输出到屏幕,以保持它与上面最初的人为示例相同。

我自己发现的一个把戏

sudo ls -hal /root/ | sudo dd of=/root/test.out

澄清一点为什么tee选项更可取

假设您有适当的权限来执行创建输出的命令,如果您将命令的输出通过管道传输给tee,那么您只需要使用sudo提升tee的权限,并指示tee写入(或追加)相关文件。

在问题中给出的例子中,这意味着:

ls -hal /root/ | sudo tee /root/test.out

举几个更实际的例子:

# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | sudo tee -a /etc/hosts

# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4

在这些示例中,您都获取了一个非特权命令的输出,并将其写入到一个通常只能由根用户写入的文件中,这就是问题的根源。

这样做是个好主意,因为生成输出的命令没有使用提升权限执行。对于echo,这似乎无关紧要,但当源命令是一个您不完全信任的脚本时,这是至关重要的。

注意,您可以使用tee的-a选项将append(如>>)附加到目标文件,而不是覆盖它(如>)。

每当我要做这样的事情时,我就变成root:

# sudo -s
# ls -hal /root/ > /root/test.out
# exit

这可能不是最好的方法,但确实有效。