我已经在我们的一个开发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的答案.
启动shell sudo -s
然后运行命令:
[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
需要重定向才能阻止T恤输出到屏幕.要追加而不是覆盖输出文件(>>
),请使用tee -a
或tee --append
(最后一个特定于GNU coreutils).
谢谢Jd,Adam J. Forster和Johnathan的第二,第三和第四个解决方案.
这里有人刚建议sudoing 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
问题是该命令在下运行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 </root/test.out EOF
或者当然:
echo 'ls -hal /root/ > /root/test.out' | sudo bash
它们具有(微小)优势,您不需要记住任何参数sudo
或sh
/bash
澄清为什么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
在每个示例中,您将获取非特权命令的输出并写入通常只能由root写入的文件,这是您的问题的起源.
这样做是个好主意,因为生成输出的命令不会使用提升的权限执行.这似乎并不重要,echo
但是当源命令是一个你不完全信任的脚本时,它是至关重要的.
请注意,您可以使用-a选项将tee追加(如>>
)附加到目标文件而不是覆盖它(如>
).
让sudo运行一个shell,如下所示:
sudo sh -c "echo foo > ~root/out"
我对这个问题的看法是:
如果您需要编写/替换文件:
echo "some text" | sudo tee /path/to/file
如果您需要附加到文件:
echo "some text" | sudo tee -a /path/to/file
写脚本怎么样?
文件名:myscript
#!/bin/sh /bin/ls -lah /root > /root/test.out # end script
然后使用sudo运行脚本:
sudo ./myscript