2016-06-21 120 views
2

在bash脚本我使用下面的命令启用IP转发:重定向输出和错误重定向命令后

echo 1 > /proc/sys/net/ipv4/ip_forward

不过,我也想包括我自己的错误信息,所以我必须重定向标准输出和stderr到/dev/null,它看起来像以下:

echo 1 > /proc/sys/net/ipv4/ip_forward >/dev/null 2>&1

这适用于没有在它重定向符号命令,为例E:

route add default gw 10.8.0.1 > /dev/null 2>&1

有没有什么办法可以使这项工作对于确实在他们重定向命令?有没有解决方法?任何其他方式我可以做得更好?

+1

目前尚不清楚您尝试解决什么问题。对于命令,每个文件描述符只能有一个重定向。 – chepner

+0

我想执行'echo 1>/proc/sys/net/ipv4/ip_forward',如果出错了,我想stderr和stdout(错误信息和输出)被重定向到/ dev/null。换句话说,当发生错误时,我不想要任何消息。 – Stan

+1

您不必再次重定向标准输出;它已经到了'/ proc/...'你只需要'echo 1>/proc/... 2>/dev/null'。 – chepner

回答

3

您的重定向是无意义的(没有违法)。

此:

echo 1 > /proc/sys/net/ipv4/ip_forward >/dev/null 2>&1 

将:

  1. 重定向echo的标准输出到/proc/sys/net/ipv4/ip_forward;
  2. 重定向echo的标准输出到/dev/null
  3. 重定向echo的标准误差到文件描述符1点,即,/dev/null

因此,全局重定向2取消重定向1:什么都不会去/proc/sys/net/ipv4/ip_forward

我想你想重定向echo的标准输出为/proc/sys/net/ipv4/ip_forwardecho的标准错误为/dev/null。这是通过:

echo 1 > /proc/sys/net/ipv4/ip_forward 2>/dev/null 

但阅读,我相信这不是你要找的答案!


你为什么要echo的标准错误重定向到/dev/nullecho很少写入标准错误。实际上,只有当写入错误时,写入标准错误的唯一时间是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固定的,因为在打击的水平发生了错误,之前甚至执行命令和重定向进行的,因为它是在那猛砸遇到一个错误重定向的时刻:它无法打开写入流并将错误消息输出到标准输出。 †

现在,我想你试图解决以下情形:当用户没有足够的权利写入/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,并重定向:

  1. 它的标准输出/dev/null;
  2. 然后将其标准误差输出到其标准输出点(即/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 
$ 

在标准错误没有错误!这是因为重定向的顺序。

+0

@Stan:正如我所说的,'echo'很少写入标准输出......你真的有一个场景,你写的'2>/dev/null'(即作为最后的重定向)是有用的吗?我会:根本不重定向标准错误,或重定向标准错误的_all_,正如我在此答案中所示(使用组或重定向标准错误_first_)。 –

+0

很少写入标准**输出**?不,我没有具体的情况说实话,因为我不是那种经验丰富的bash,我只是想讽刺任何错误“以防万一”。 – Stan

+0

我的意思是_standard **错误** _ ... –

1

解决

echo 1 > /proc/sys/net/ipv4/ip_forward ip_forward 2>/dev/null

echo 1是标准输出一部分,所以此不必再被重定向。我只需要添加2>/dev/null来重定向stderr。

+1

未解决。'ip_forward'已经重定向它的标准输出,所以它不产生输出。你所做的与echo 1> .../ip_forward 2>/dev/null没有区别。 – mob

+0

你可能对第一部分是正确的。但是使用函数1实际上会回传给'.../ip_forward'。当使用echo 1> .../ip_forward 2>/dev/null 2>&1'时,我的'.../ip_forward'文件保持为0。我不确定它是否能正确重定向stdout和stderr。 – Stan