如何使用sudo将输出重定向到我无权写入的位置?
我已经在我们的RedHat linux的一个开发箱上获得了sudo访问权限,而且我似乎常常需要将输出重定向到我通常没有写权限的位置。
麻烦的是,这个人为的例子不起作用:
sudo ls -hal /root/ > /root/test.out
我刚收到回复:
-bash: /root/test.out: Permission denied
我怎样才能使这个工作?
您的命令不起作用,因为重定向是由您的shell执行的,而该shell没有写入/root/test.out
的权限。 输出的重定向不是由sudo执行的。
有多种解决方案:
-
使用sudo运行一个shell,并使用
-c
选项给该命令:sudo sh -c 'ls -hal /root/ > /root/test.out'
-
用你的命令创建一个脚本,并用sudo运行脚本:
#!/bin/sh ls -hal /root/ > /root/test.out
运行
sudo ls.sh
如果您不想创建临时文件,请参阅Steve Bennett的答案 。 -
用
sudo -s
启动一个shell然后运行你的命令:[nobody@so]$ sudo -s [root@so]# ls -hal /root/ > /root/test.out [root@so]# ^D [nobody@so]$
-
使用
sudo tee
(如果在使用-c
选项时必须转义很多):sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
重定向到
/dev/null
需要停止输出到屏幕。 要追加而不是覆盖输出文件(>>
),请使用tee -a
或tee --append
(最后一个特定于GNU coreutils )。
感谢Jd , Adam J. Forster和Johnathan提供了第二,第三和第四个解决方案。
这里有人建议sudoing tee:
sudo ls -hal /root/ | sudo tee /root/test.out > /dev/null
这也可以用来将任何命令重定向到一个你无权访问的目录。 它的工作原理是因为T恤程序实际上是一个“对文件的回应”程序,而重定向到/ dev / null是为了停止它,并输出到屏幕上保持它与上面的原始设计的例子相同。
我弄明白了自己的一招
sudo ls -hal /root/ | sudo dd of=/root/test.out
问题是命令在sudo
下运行,但是重定向在用户下运行。 这是由shell完成的,你可以做的很少。
sudo command > /some/file.log `-----v-----'`-------v-------' command redirection
通常的绕过这个方法是:
-
将这些命令包装在一个你在sudo下调用的脚本中。
如果命令和/或日志文件发生更改,则可以使脚本将这些参数作为参数。 例如:
sudo log_script command /log/file.txt
-
调用一个shell,并将命令行作为参数传递给
-c
这对于一个复合命令是特别有用的。 例如:
sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt
另一个主题变化是:
sudo bash <<EOF ls -hal /root/ > /root/test.out EOF
或者当然:
echo 'ls -hal /root/ > /root/test.out' | sudo bash
他们有(小)优势,你不需要记住sudo
或sh
/ bash
任何参数
让sudo运行一个shell,像这样:
sudo sh -c "echo foo > ~root/out"
澄清一下为什么T恤选项是可取的
假设你有适当的权限来执行创建输出的命令,如果你将你的命令的输出用管道输出,你只需要用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
在这些例子中的每一个中,您都将获得非特权命令的输出,并写入通常只能由root写入的文件,这是您的问题的根源。
这样做是个好主意,因为生成输出的命令不会以提升的权限执行。 在这里echo
并不重要,但是当源代码命令是一个你完全不信任的脚本时,这是至关重要的。
请注意,您可以使用-a选项来将追加追加(如>>
)到目标文件而不是覆盖它(如>
)。
如何编写脚本?
文件名:myscript
#!/bin/sh /bin/ls -lah /root > /root/test.out # end script
然后使用sudo来运行脚本:
sudo ./myscript
我会去解决这个问题的方法是:
如果您需要编写/替换文件:
echo "some text" | sudo tee /path/to/file
如果你需要附加到文件:
echo "some text" | sudo tee -a /path/to/file
每当我必须做这样的事情,我只是成为根:
# sudo -s # ls -hal /root/ > /root/test.out # exit
这可能不是最好的方式,但它的工作原理。
我会这样做:
sudo su -c 'ls -hal /root/ > /root/test.out'
这是涉及三通的答案的延伸。 为了使事情变得更简单,你可能需要创建一个小脚本(我称之为suwrite,或者你可以称它为sutee),并把它放在/ usr / local / bin /中,并且带有+ x权限:
#! /bin/sh sudo tee $@ > /dev/null
现在你所要做的就是将输出传送给这个脚本,然后是所需的超级用户可访问的文件名,如果需要的话它会自动提示你输入你的密码(因为它包括sudo)。
echo test | suwrite /root/test.txt
请注意,由于这是一个简单的三通包装,它也将接受三通的-a(或任何其他)选项,以追加到您刚刚传递的所需文件-a:
echo test | suwrite -a /root/test.txt
也许你被授予sudo访问只有一些程序/路径? 那么没有办法做你想做的事情。 (除非你会以某种方式破解)
如果不是这样的话,也许你可以写bash脚本:
cat > myscript.sh #!/bin/sh ls -hal /root/ > /root/test.out
按ctrl + d :
chmod a+x myscript.sh sudo myscript.sh
希望它有帮助。
不要吝啬一匹死马,但这里有太多的答案,使用tee
,这意味着你必须重定向stdout
到/dev/null
除非你想在屏幕上看到一个副本。 一个简单的解决方案就是像这样使用cat
:
sudo ls -hal /root/ | sudo bash -c "cat > /root/test.out"
请注意,重定向是如何放置在引号内的,以便通过由sudo
启动的shell来执行,而不是运行该sudo
的shell。
sudo at now at> echo test > /tmp/test.out at> <EOT> job 1 at Thu Sep 21 10:49:00 2017