在 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
有什么方法可以使此功能适用于确实有重定向的命令吗?有解决方法吗?还有其他方法我可以做得更好吗?
您的重定向毫无意义(无意冒犯)。
\n\n这:
\n\necho 1 > /proc/sys/net/ipv4/ip_forward >/dev/null 2>&1\nRun Code Online (Sandbox Code Playgroud)\n\n将要:
\n\necho将的标准输出重定向到/proc/sys/net/ipv4/ip_forward;echo将标准输出重定向到/dev/nullecho的标准错误重定向到文件描述符指向的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\nRun Code Online (Sandbox Code Playgroud)\n\n但请继续阅读,我相信这不是您正在寻找的答案!
\n\n为什么要将echo的标准错误重定向到/dev/null?\necho很少写入标准错误。事实上,只有在echo出现写入错误时才会写入标准错误。有几种可能发生这种情况的方式:
如果磁盘已满(可以用 模拟/dev/full):
$ echo hello >/dev/full\nbash: echo: write error: No space left on device\n$ echo hello >/dev/full 2>/dev/null\n$\nRun Code Online (Sandbox Code Playgroud)\n\n(重定向时不显示任何错误消息2>/dev/null)。
ifecho的标准输出已关闭:
$ ( exec >&-; echo hello )\nbash: echo: write error: Bad file descriptor\n$ ( exec >&-; echo hello 2> /dev/null )\n$\nRun Code Online (Sandbox Code Playgroud)\n\n(重定向时不显示任何错误消息2>/dev/null)。
可能还有其他情况echo输出为标准错误。但以下肯定不在其中:
将echo的标准输出重定向到不存在的文件描述符:
$ echo hello >&42\nbash: 42: Bad file descriptor\n$ echo hello >&42 2>/dev/null\nbash: 42: Bad file descriptor\n$\nRun Code Online (Sandbox Code Playgroud)\n\n重定向2>/dev/null并不能解决任何问题;您实际上可以看到错误来自于bash而不是来自echo(后者将作为bash: echo:前缀)。
将echo的标准输出重定向到没有写权限的文件:
$ touch testfile\n$ chmod -w testfile\n$ echo hello > testfile\nbash: testfile: Permission denied\n$ echo hello > testfile 2>/dev/null\nbash: testfile: Permission denied\n$\nRun Code Online (Sandbox Code Playgroud)\n\n与上面相同,重定向2>/dev/null不会解决任何问题。
前面的情况没有被 修复2>/dev/null,因为错误发生在 Bash 级别,甚至在执行命令和执行重定向之前,因为在重定向时 Bash 遇到错误:它无法打开用于写入的流并将错误消息输出到标准输出。†
现在我猜您正在尝试修复以下情况:当用户没有足够的权限写入时/proc/sys/net/ipv4/ip_forward:
$ echo 1 >/proc/sys/net/ipv4/ip_forward\nbash: /proc/sys/net/ipv4/ip_forward: Permission denied\n$\nRun Code Online (Sandbox Code Playgroud)\n\n标准错误上的错误消息无法通过简单的重定向进行重定向‡:
\n\n$ echo 1 >/proc/sys/net/ipv4/ip_forward 2>/dev/null\nbash: /proc/sys/net/ipv4/ip_forward: Permission denied\n$\nRun Code Online (Sandbox Code Playgroud)\n\n重定向在重定向级别(即在执行命令之前)发生的错误的标准方法是使用分组:
\n\n$ { echo 1 >/proc/sys/net/ipv4/ip_forward; } 2>/dev/null\nRun Code Online (Sandbox Code Playgroud)\n\n现在这解释了为什么您作为答案发布的解决方案有效:让我们仔细研究一下,我们会发现有些东西表明您没有完全理解重定向(希望这篇文章将帮助您理解一些事情);你的代码是:
\n\nfunction ip_forward\n{\n echo 1 > /proc/sys/net/ipv4/ip_forward\n}\nip_forward >/dev/null 2>&1\nRun Code Online (Sandbox Code Playgroud)\n\n这将运行该函数ip_forward并重定向:
/dev/null;/dev/null)。但该函数ip_forward不会向标准输出输出任何内容!所以重定向只对重定向的部分>/dev/null有用。事实上,您的代码完全等同于:2>&1
function ip_forward\n{\n echo 1 > /proc/sys/net/ipv4/ip_forward\n}\nip_forward 2>/dev/null\nRun Code Online (Sandbox Code Playgroud)\n\n但是(因为您只是使用函数构造来实现您想要的\xe2\x80\x94,而不是因为您想要一个函数),所以最好将代码编写为:
\n\necho 1 2>/dev/null >/proc/sys/net/ipv4/ip_forward\nRun Code Online (Sandbox Code Playgroud)\n\n或者
\n\n{ echo 1 > /proc/sys/net/ipv4/ip_forward; } 2>/dev/null\nRun Code Online (Sandbox Code Playgroud)\n\n(后者是首选)。
\n\n抱歉这篇长文!
\n\n† \n有一点我们应该注意:重定向的顺序。Bash 读取它们时,它们是从左到右执行的。我们首先重定向标准错误,然后将标准输出重定向到不存在/不可写的流怎么样?
\n\n$ echo hello 2>/dev/null >&42\n$\nRun Code Online (Sandbox Code Playgroud)\n\n没错,它有效。
\n\n‡ \n好吧,可以,如果你理解前面的脚注:
\n\n$ echo 1 2>/dev/null >/proc/sys/net/ipv4/ip_forward\n$ echo $?\n1\n$\nRun Code Online (Sandbox Code Playgroud)\n\n标准错误没有错误!这是因为重定向的顺序。
\n| 归档时间: |
|
| 查看次数: |
358 次 |
| 最近记录: |