问题描述
关于使用sudo
和输出重定向>
,我有一个小问题。要启用IP转发,有人可以使用以下命令:
echo 1 > /proc/sys/net/ipv4/ip_forward
执行此命令将拒绝权限,因为它需要root权限。但是,使用sudo
执行相同的命令也会给出权限被拒绝错误!似乎输出重定向>
不继承前面命令echo
的权限。这是正确的吗?
作为一种解决方法,我做:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
这是最好的方法吗?我错过了什么吗?
请注意,这是一个示例,它适用于使用输出重定向的所有命令。
最佳解决方案
您使用sudo tee
的方法很好。使用sudo tee
的一个好结果是管道之前执行的命令不会以root身份运行。如果您只需要一个不需要root权限的程序输出,那么这很有用。
如果您不关心管道之前使用的程序的输出(在本例中为echo 1
),请将stdout重定向到/dev/null
:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward > /dev/null
以上相当于sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
,区别在于echo 1
以root身份运行。
如果需要附加到特权文件,可以使用sh -c 'echo 127.0.0.1 local.host >> /etc/hosts'
或:
echo 127.0.0.1 local.host | sudo tee -a /etc/hosts
注意-a
是--append
的简写。
次佳解决方案
一种解决方案是使用:
sudo bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
但是这个没有从父shell继承env属性,所以你不能使用它来例如echo $PATH
来获得你父shell中的相同结果(当然只有你改变你的路径属性) 。
使用sudo -E
将保留环境变量。
此外,根据https://wiki.ubuntu.com/DashAsBinSh,您最好使用sh
(它是dash
的符号链接),而不是使用bash
调用它。
所以,您可以将其重写为:
sudo -E sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
第三种解决方案
我通常使用sudo bash -c
技巧,或者首先执行sudo -s
以保持root,然后运行重定向命令。
它不能以第一种方式工作的原因是shell首先处理重定向,然后运行sudo
。由于您的shell无权访问该文件,因此重定向失败。