我怎么还记得如何使用重定向?


40

我知道

  program > /dev/null 2>&1 

做。它将输出重定向到,/dev/null2>&1意味着将错误输出重定向到发送输出的同一位置。

我的问题是我总是不得不用谷歌搜索它,因为我不记得了。

所以,我尝试&2>11>2&1>&2...我尝试各种组合,直到我google一下...

容易记住的诀窍是什么?


我遇到了同样的问题,因此我以“冗长”的方式进行操作-都重定向program 1> /dev/null 2>/dev/null。有时候,您确实需要将stdout和混合stderr在一起以查看实际情况-例如将复杂的编译过程的输出重定向到文件。在那种情况下,我最终将其谷歌搜索
ivanivan '18

Answers:


20

输出胜于错误,因此输出优先(1 vs 2)。

>是“前往”的简写。左边是我要发送的内容,右边是我要发送的内容。由于“ where”(几乎)始终是文件,因此类似

program > /dev/null 2>1

将重定向到名为1的文件。因此,“&”号(&)将文件修改为文件描述符。

不幸的是,我没有遇到过自己的助记符,也没有开发过自己的助记符,但是当我第一次学习* nix时,我发现了这种合理的工作方式。经过几次尝试后,它就成为了第二天性。


你的第一句话对我来说没有意义。 stdout是文件描述符1,stderr是2。因此,“错误”在“输出”之前。
沃伦·杨

该句子是记住哪个文件描述符stdoutstderr引用的助记符。
gvkv

好的,但是它似乎仍然令人困惑,因为最初的问题是关于尝试记住“ 2>&1”咒语中字符的顺序。
沃伦·杨

9

一种技巧是记住1 =标准输出,2 =标准错误。所以:

2>&1=标准错误流进入标准输出流。
1>&2反之亦然。

如果您曾经使用类似C的语言进行编程,则很容易记住&符号(&)。我选择将其视为现有文件描述符的“地址”,这样您就不必更改文件本身或创建新文件。



5

实际上,这取决于您使用的外壳。Bash通常非常宽容,您可以这样做:

program &> file

5

让我们考虑以下三个选项:

program  2>1
program  2>1& 
program  2>&1

第一个将stderr发送到文件名“ 1”:毕竟,bash希望重定向到文件。

第二个也重定向到相同的文件,但program在后台运行:这就是尾随的&含义。

剩下的第三种可能性是bash领域中唯一有意义的重定向到文件句柄的可能性。

如何记住0、1、2中的哪个?考虑从控制台运行计算机。首先,您必须输入一些内容(0 = stdin)。然后,您看到输出(1 = stdout)。最后,只有出现问题时,您才能看到stderr(2)。


1

将其绘制在墙纸中。

现在,认真地讲,我一直忘了这些以及其他基本内容,因此我向自己开发的应用程序中添加了一个快速提示菜单,该应用程序我每天都会使用。您可能想尝试一下,或使用gnote之类的东西来做笔记。


1

关于bash shell,我发现记住的最佳方法是通过了解正在发生的事情。
如果您只想记住如何正确设置命令,则可以尝试

program > /results 2> /results

那是很明显的事情,很容易记住。即

  • 1 STDOUT将 /results
  • 2STDERR也要去直接/results

问题是这不符合您的预期。考虑以下:

文件: /tmp/poem.txt

the quick brown fox jumped over the lazy dog

然后运行命令

grep "brown" /tmp/poem.txt NOT_A_FILE > /tmp/results 2> /tmp/results

然后

$ cat /tmp/results
grep: NOT_A_FILE: No such file or directory
 lazy dog

这里发生了什么?
我的理解是bash设置重定向,将STDERR 直接指向文件,/tmp/results并且由于其性质,>它会做两件事

  1. 通常创建一个新文件-在这种情况下,机会已经过去了,因为bash在生成输出时已经越过了此例程。
  2. 直接插入文件的开头。而不是像添加一样>>

因此,在这种情况下,STDERR直接插入到/tmp/results覆盖STDOUT输出的开头。
注意:如果您过去>>附加了内容,则可能无法使用此语法。
但是,要解决此问题,您需要-无需直接将STDERR重定向到文件,而是 STDERR的输出合并到STDOUT流中,这样就不会发生冲突。
使用运算2>&1符运算符可实现此目的

grep "brown" poem.txt NOT_A_FILE > /tmp/results 2>&1

&允许的bash从一个文件名为区分 11文件描述符。
对我来说,该语句2>&1本身可以准确说明正在发生的事情-STDERR本身已在STDOUT上重定向-并最终以/tmp/results这种方式指向STDOUT(几乎是副作用)。
与许多指南所声称的相反,这是2>&1将STDERR发送到任何指向STDOUT的位置。如果是这样-您仍然会遇到覆盖问题。

有关更多信息,请参见-http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.