sudo ls -hal /root/ > /root/test.out
-bash: /root/test.out: Permission denied
您的命令不起作用,因为重定向是由您的外壳执行的,该外壳无权写入/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输出到屏幕。要附加而不是覆盖输出文件( >>
),请使用tee -a
或tee --append
(最后一个特定于GNU coreutils )。
感谢Jd , Adam J. Forster和Johnathan提供第二,第三和第四种解决方案。
这里有人建议 steeing 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 <<EOF
ls -hal /root/ > /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
无关紧要,但是当 source 命令是您不完全信任的脚本时,它至关重要。
请注意,您可以使用 - 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
我会这样:
sudo su -c 'ls -hal /root/ > /root/test.out'