在bash脚本中,我使用以下命令启用IP转发:
echo 1 > /proc/sys/net/ipv4/ip_forward
但是,我也想包含自己的错误消息,因此我必须将stdout和stderr重定向到/dev/null
,如下所示:
echo 1 > /proc/sys/net/ipv4/ip_forward >/dev/null 2>&1
这适用于其中没有重定向符号的命令,例如:
route add default gw 10.8.0.1 > /dev/null 2>&1
对于有重定向的命令,我有什么办法可以使它起作用?有解决方法吗?还有其他方法可以更好地做到这一点吗?
您的重定向是荒谬的(没有冒犯性)。
这:
echo 1 > /proc/sys/net/ipv4/ip_forward >/dev/null 2>&1
将要:
echo
标准输出重定向到/proc/sys/net/ipv4/ip_forward
;echo
标准输出重定向到/dev/null
echo
标准错误重定向到文件描述符1
指向的位置,即/dev/null
。因此,全局地,重定向2取消了重定向1:什么也不会去/proc/sys/net/ipv4/ip_forward
!
我猜您想将echo
标准输出重定向到/proc/sys/net/ipv4/ip_forward
和将echo
标准错误重定向到/dev/null
。这可以通过以下方法实现:
echo 1 > /proc/sys/net/ipv4/ip_forward 2>/dev/null
但是请继续阅读,我相信这不是您要找的答案!
为什么要将echo
标准错误重定向到/dev/null
?echo
很少写入标准错误。实际上,唯一echo
会写入标准错误的时间是发生写入错误时。有两种方法可能会发生这种情况:
如果磁盘已满(可以使用模拟/dev/full
):
$ echo hello >/dev/full
bash: echo: write error: No space left on device
$ echo hello >/dev/full 2>/dev/null
$
(没有显示带有重定向的错误消息2>/dev/null
)。
如果echo
标准输出已关闭:
$ ( exec >&-; echo hello )
bash: echo: write error: Bad file descriptor
$ ( exec >&-; echo hello 2> /dev/null )
$
(没有显示带有重定向的错误消息2>/dev/null
)。
在其他情况下,可能会echo
输出标准错误。但是以下内容当然不在其中:
将echo
的标准输出重定向到不存在的文件描述符:
$ echo hello >&42
bash: 42: Bad file descriptor
$ echo hello >&42 2>/dev/null
bash: 42: Bad file descriptor
$
重定向2>/dev/null
无法解决任何问题;您实际上可以看到错误来自bash
而不是来自错误echo
(后者将bash: echo:
作为前缀)。
将echo
的标准输出重定向到没有写许可权的文件:
$ touch testfile
$ chmod -w testfile
$ echo hello > testfile
bash: testfile: Permission denied
$ echo hello > testfile 2>/dev/null
bash: testfile: Permission denied
$
与上述相同,重定向2>/dev/null
无法解决任何问题。
之前的情况不是由固定的2>/dev/null
,因为错误发生在Bash级别,甚至在命令执行和重定向之前就发生了,因为在重定向的那一刻Bash遇到错误:它无法打开要写入的流并将错误消息输出到标准输出。†
现在,我猜您正在尝试修复以下情况:当用户没有足够的权限来写入时/proc/sys/net/ipv4/ip_forward
:
$ echo 1 >/proc/sys/net/ipv4/ip_forward
bash: /proc/sys/net/ipv4/ip_forward: Permission denied
$
标准错误的错误消息无法通过简单的重定向‡重定向:
$ echo 1 >/proc/sys/net/ipv4/ip_forward 2>/dev/null
bash: /proc/sys/net/ipv4/ip_forward: Permission denied
$
重定向在重定向级别(即,甚至在执行命令之前)发生的错误的标准方法是使用分组:
$ { echo 1 >/proc/sys/net/ipv4/ip_forward; } 2>/dev/null
现在,这说明了您发布作为答案的解决方案的原因:让我们仔细研究一下,我们会发现有些事情表明您不完全了解重定向(希望这篇文章将帮助您了解一些事情);您的代码是:
function ip_forward
{
echo 1 > /proc/sys/net/ipv4/ip_forward
}
ip_forward >/dev/null 2>&1
这将运行函数ip_forward
,并重定向:
/dev/null
;/dev/null
)。但是该函数ip_forward
不会将任何输出输出到标准输出!所以重定向>/dev/null
是只对有用2>&1
的重定向的一部分。实际上,您的代码完全等同于:
function ip_forward
{
echo 1 > /proc/sys/net/ipv4/ip_forward
}
ip_forward 2>/dev/null
但是,然后(由于仅使用函数构造作为实现所需功能的方式,而并非因为需要函数),因此最好编写以下任一代码:
echo 1 2>/dev/null >/proc/sys/net/ipv4/ip_forward
或者
{ echo 1 > /proc/sys/net/ipv4/ip_forward; } 2>/dev/null
(首选)。
对不起,这篇长文章!
†我们应该注意一些事项:重定向顺序。当Bash读取它们时,它们从左到右执行。我们如何首先将标准错误重定向,然后将标准输出重定向到不存在/不可写的流中呢?
$ echo hello 2>/dev/null >&42
$
没错,它有效。
‡好吧,如果您理解上一个脚注,可以:
$ echo 1 2>/dev/null >/proc/sys/net/ipv4/ip_forward
$ echo $?
1
$
标准错误无错误!那是因为重定向的顺序。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句