Linux 对标准输入、标准输出和标准错误感到困惑?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3385201/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Confused about stdin, stdout and stderr?
提问by Shouvik
I am rather confused with the purpose of these three files. If my understanding is correct, stdin
is the file in which a program writes into its requests to run a task in the process, stdout
is the file into which the kernel writes its output and the process requesting it accesses the information from, and stderr
is the file into which all the exceptions are entered. On opening these files to check whether these actually do occur, I found nothing seem to suggest so!
我对这三个文件的目的感到困惑。如果我的理解是正确的,stdin
是程序写入其在进程中运行任务的请求stdout
的文件,是内核写入其输出的文件以及请求它从中访问信息的进程stderr
的文件,还是该文件输入所有异常。在打开这些文件以检查这些文件是否确实发生时,我发现似乎没有任何提示!
What I would want to know is what exactly is the purpose of these files, absolutely dumbed down answer with very little tech jargon!
我想知道的是这些文件的目的到底是什么,用很少的技术术语绝对愚蠢的回答!
采纳答案by paxdiablo
Standard input- this is the file handlethat your process reads to get information from you.
标准输入- 这是您的进程读取以从您那里获取信息的文件句柄。
Standard output- your process writes normal information to this file handle.
标准输出- 您的进程将正常信息写入此文件句柄。
Standard error- your process writes error information to this file handle.
标准错误- 您的进程将错误信息写入此文件句柄。
That's about as dumbed-down as I can make it :-)
这是我能做到的最愚蠢的:-)
Of course, that's mostly by convention. There's nothing stopping you from writing your error information to standard output if you wish. You can even close the three file handles totally and open your own files for I/O.
当然,这主要是约定俗成的。如果您愿意,没有什么可以阻止您将错误信息写入标准输出。您甚至可以完全关闭三个文件句柄并打开您自己的 I/O 文件。
When your process starts, it should already have these handles open and it can just read from and/or write to them.
当您的进程启动时,它应该已经打开了这些句柄,并且可以读取和/或写入它们。
By default, they're probably connected to your terminal device (e.g., /dev/tty
) but shells will allow you to set up connections between these handles and specific files and/or devices (or even pipelines to other processes) before your process starts (some of the manipulations possible are rather clever).
默认情况下,它们可能已连接到您的终端设备(例如,/dev/tty
),但 shell 将允许您在您的进程开始之前(某些可能的操作相当聪明)。
An example being:
一个例子是:
my_prog <inputfile 2>errorfile | grep XYZ
which will:
这将:
- create a process for
my_prog
. - open
inputfile
as your standard input (file handle 0). - open
errorfile
as your standard error (file handle 2). - create anotherprocess for
grep
. - attach the standard output of
my_prog
to the standard input ofgrep
.
- 创建一个进程
my_prog
。 inputfile
作为标准输入打开(文件句柄 0)。errorfile
作为标准错误打开(文件句柄 2)。- 为.创建另一个进程
grep
。 - 将 的标准输出附加
my_prog
到 的标准输入grep
。
Re your comment:
回复您的评论:
When I open these files in /dev folder, how come I never get to see the output of a process running?
当我在 /dev 文件夹中打开这些文件时,为什么我永远看不到正在运行的进程的输出?
It's because they're not normal files. While UNIX presents everythingas a file in a file system somewhere, that doesn't make it so at the lowest levels. Most files in the /dev
hierarchy are either character or block devices, effectively a device driver. They don't have a size but they do have a major and minor device number.
这是因为它们不是普通文件。尽管 UNIX 将所有内容都作为文件系统中某处的文件呈现,但在最低级别上却并非如此。/dev
层次结构中的大多数文件是字符设备或块设备,实际上是设备驱动程序。它们没有大小,但有主要和次要设备号。
When you open them, you're connected to the device driver rather than a physical file, and the device driver is smart enough to know that separate processes should be handled separately.
当您打开它们时,您连接到设备驱动程序而不是物理文件,并且设备驱动程序足够聪明,知道应该单独处理单独的进程。
The same is true for the Linux /proc
filesystem. Those aren't real files, just tightly controlled gateways to kernel information.
Linux/proc
文件系统也是如此。这些不是真正的文件,只是对内核信息进行严格控制的网关。
回答by Jim Lewis
It would be more correct to say that stdin
, stdout
, and stderr
are "I/O streams" rather
than files. As you've noticed, these entities do not live in the filesystem. But the
Unix philosophy, as far as I/O is concerned, is "everything is a file". In practice,
that really means that you can use the same library functions and interfaces (printf
,
scanf
, read
, write
, select
, etc.) without worrying about whether the I/O stream
is connected to a keyboard, a disk file, a socket, a pipe, or some other I/O abstraction.
更准确地说stdin
,stdout
, 和stderr
是“I/O 流”而不是文件。正如您所注意到的,这些实体并不存在于文件系统中。但就 I/O 而言,Unix 哲学是“一切都是文件”。实际上,这真的意味着您可以使用相同的库函数和接口(printf
、
scanf
、read
、write
、select
等),而不必担心 I/O 流是否连接到键盘、磁盘文件、套接字、管道、或其他一些 I/O 抽象。
Most programs need to read input, write output, and log errors, so stdin
, stdout
,
and stderr
are predefined for you, as a programming convenience. This is only
a convention, and is not enforced by the operating system.
大多数程序需要读取输入,输出写入和错误日志,所以stdin
,stdout
和stderr
预定义的你,作为一个编程方便。这只是一个约定,并不由操作系统强制执行。
回答by mikek3332002
stdin
标准输入
Reads input through the console (e.g. Keyboard input). Used in C with scanf
通过控制台读取输入(例如键盘输入)。在 C 中与 scanf 一起使用
scanf(<formatstring>,<pointer to storage> ...);
stdout
标准输出
Produces output to the console. Used in C with printf
产生输出到控制台。在 C 中与 printf 一起使用
printf(<string>, <values to print> ...);
stderr
标准错误
Produces 'error' output to the console. Used in C with fprintf
向控制台生成“错误”输出。在 C 中与 fprintf 一起使用
fprintf(stderr, <string>, <values to print> ...);
Redirection
重定向
The source for stdin can be redirected. For example, instead of coming from keyboard input, it can come from a file (echo < file.txt
), or another program ( ps | grep <userid>
).
stdin 的源可以重定向。例如,它可以来自文件 ( echo < file.txt
) 或其他程序 ( ps | grep <userid>
) ,而不是来自键盘输入。
The destinations for stdout, stderr can also be redirected. For example stdout can be redirected to a file: ls . > ls-output.txt
, in this case the output is written to the file ls-output.txt
. Stderr can be redirectedwith 2>
.
stdout、stderr 的目标也可以重定向。例如,标准输出可以重定向到一个文件:ls . > ls-output.txt
,在这种情况下,输出被写入文件ls-output.txt
。 Stderr 可以使用2>
.
回答by sarnold
I'm afraid your understanding is completely backwards. :)
恐怕你的理解是完全倒退的。:)
Think of "standard in", "standard out", and "standard error" from the program'sperspective, not from the kernel's perspective.
从程序的角度而不是从内核的角度考虑“标准输入”、“标准输出”和“标准错误” 。
When a program needs to print output, it normally prints to "standard out". A program typically prints output to standard out with printf
, which prints ONLY to standard out.
当程序需要打印输出时,它通常会打印到“标准输出”。程序通常使用 将输出打印到标准输出printf
,它只打印到标准输出。
When a program needs to print error information (not necessarily exceptions, those are a programming-language construct, imposed at a much higher level), it normally prints to "standard error". It normally does so with fprintf
, which accepts a file stream to use when printing. The file stream could be any file opened for writing: standard out, standard error, or any other file that has been opened with fopen
or fdopen
.
当程序需要打印错误信息(不一定是异常,那些是编程语言结构,在更高的级别上强加)时,它通常会打印为“标准错误”。它通常使用fprintf
,它接受在打印时使用的文件流。文件流可以是为写入而打开的任何文件:标准输出、标准错误或已使用fopen
或打开的任何其他文件fdopen
。
"standard in" is used when the file needs to read input, using fread
or fgets
, or getchar
.
当文件需要读取输入时使用“标准输入”,使用fread
or fgets
, or getchar
。
Any of these files can be easily redirectedfrom the shell, like this:
这些文件中的任何一个都可以轻松地从 shell重定向,如下所示:
cat /etc/passwd > /tmp/out # redirect cat's standard out to /tmp/foo
cat /nonexistant 2> /tmp/err # redirect cat's standard error to /tmp/error
cat < /etc/passwd # redirect cat's standard input to /etc/passwd
Or, the whole enchilada:
或者,整个辣酱玉米饼馅:
cat < /etc/passwd > /tmp/out 2> /tmp/err
There are two important caveats: First, "standard in", "standard out", and "standard error" are just a convention. They are a very strongconvention, but it's all just an agreement that it is very nice to be able to run programs like this: grep echo /etc/services | awk '{print $2;}' | sort
and have the standard outputs of each program hooked into the standard input of the next program in the pipeline.
有两个重要的警告:首先,“标准输入”、“标准输出”和“标准错误”只是一个约定。它们是一个非常强大的约定,但这只是一个协议,能够运行这样的程序是非常好的:grep echo /etc/services | awk '{print $2;}' | sort
并将每个程序的标准输出连接到管道中下一个程序的标准输入中。
Second, I've given the standard ISO C functions for working with file streams (FILE *
objects) -- at the kernel level, it is all file descriptors (int
references to the file table) and much lower-level operations like read
and write
, which do not do the happy buffering of the ISO C functions. I figured to keep it simple and use the easier functions, but I thought all the same you should know the alternatives. :)
其次,我已经给出了用于处理文件流(FILE *
对象)的标准 ISO C 函数——在内核级别,它是所有文件描述符(int
对文件表的引用)和像read
andwrite
这样的低级操作,它们不做 ISO C 函数的快乐缓冲。我想保持简单并使用更简单的功能,但我认为你应该知道替代方案。:)
回答by Sam
Using ps -aux reveals current processes, all of which are listed in /proc/ as /proc/(pid)/, by calling cat /proc/(pid)/fd/0 it prints anything that is found in the standard output of that process I think. So perhaps,
使用 ps -aux 显示当前进程,所有这些进程都在 /proc/ 中列为 /proc/(pid)/,通过调用 cat /proc/(pid)/fd/0 它打印在标准输出中找到的任何内容我认为的那个过程。所以也许,
/proc/(pid)/fd/0 - Standard Output File
/proc/(pid)/fd/1 - Standard Input File
/proc/(pid)/fd/2 - Standard Error File
/proc/(pid)/fd/0 - 标准输出文件
/proc/(pid)/fd/1 - 标准输入文件
/proc/(pid)/fd/2 - 标准错误文件
for example
例如
But only worked this well for /bin/bash other processes generally had nothing in 0 but many had errors written in 2
但仅适用于 /bin/bash 其他进程通常在 0 中没有任何内容,但许多在 2 中写入错误
回答by dee
I think people saying stderr
should be used only for error messages is misleading.
我认为人们说stderr
应该仅用于错误消息是一种误导。
It should also be used for informative messages that are meant for the user running the command and not for any potential downstream consumers of the data (i.e. if you run a shell pipe chaining several commands you do not want informative messages like "getting item 30 of 42424" to appear on stdout
as they will confuse the consumer, but you might still want the user to see them.
它也应该用于为运行命令的用户而不是数据的任何潜在下游消费者的信息性消息(即,如果您运行链接多个命令的 shell 管道,您不想要信息性消息,例如“获取第 30 42424" 出现,stdout
因为它们会使消费者感到困惑,但您可能仍然希望用户看到它们。
See thisfor historical rationale:
请参阅此以了解历史原理:
"All programs placed diagnostics on the standard output. This had always caused trouble when the output was redirected into a ?le, but became intolerable when the output was sent to an unsuspecting process. Nevertheless, unwilling to violate the simplicity of the standard-input-standard-output model, people tolerated this state of affairs through v6. Shortly thereafter Dennis Ritchie cut the Gordian knot by introducing the standard error ?le. That was not quite enough. With pipelines diagnostics could come from any of several programs running simultaneously. Diagnostics needed to identify themselves."
“所有程序都在标准输出上放置了诊断。当输出被重定向到一个文件时,这总是会引起问题,但是当输出被发送到一个毫无戒心的进程时变得无法忍受。然而,不愿意违反标准输入的简单性-标准输出模型,人们通过 v6 容忍这种状态。此后不久,丹尼斯·里奇通过引入标准错误文件打破了戈尔迪安的结。这还不够。有了管道,诊断可以来自多个同时运行的程序中的任何一个。需要诊断来识别自己。”
回答by Bahruz Balabayov
A file with associated buffering is called a stream and is declared to be a pointer to a defined type FILE. The fopen() function creates certain descriptive data for a stream and returns a pointer to designate the stream in all further transactions. Normally there are three open streams with constant pointers declared in the header and associated with the standard open files. At program startup three streams are predefined and need not be opened explicitly: standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). When opened the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device
具有关联缓冲的文件称为流,并被声明为指向已定义类型 FILE 的指针。fopen() 函数为流创建某些描述性数据并返回一个指针以在所有后续事务中指定流。通常有三个打开的流,在头中声明了常量指针,并与标准打开文件相关联。在程序启动时,预定义了三个流,无需明确打开:标准输入(用于读取常规输入)、标准输出(用于写入常规输出)和标准错误(用于写入诊断输出)。打开时,标准错误流未完全缓冲;标准输入和标准输出流被完全缓冲当且仅当可以确定该流不引用交互式设备
回答by geekanil
stderr will not do IO Cache buffering so if our application need to print critical message info (some errors ,exceptions) to console or to file use it where as use stdout to print general log info as it use IO Cache buffering there is a chance that before writing our messages to file application may close ,leaving debugging complex
stderr 不会进行 IO 缓存缓冲,因此如果我们的应用程序需要将关键消息信息(某些错误、异常)打印到控制台或文件,请使用它,使用 stdout 打印一般日志信息,因为它使用 IO 缓存缓冲有可能在将我们的消息写入文件之前,应用程序可能会关闭,从而使调试变得复杂
回答by Leopold Gault
As a complement of the answers above, here is a sum up about Redirections:
EDIT: This graphic is not entirely correct but I am not sure why...
编辑:这个图形并不完全正确,但我不知道为什么......
The graphic says 2>&1 has the same effect as &> however
该图形表示 2>&1 与 &> 具有相同的效果,但是
ls Documents ABC > dirlist 2>&1
#does not give the same output as
ls Documents ABC > dirlist &>
回答by Margach Chris
For authoritative information about these files, check out the man pages, run the command on your terminal.
有关这些文件的权威信息,请查看手册页,在终端上运行命令。
$ man stdout
But for a simple answer, each file is for:
但是对于一个简单的答案,每个文件都用于:
stdoutfor a stream out
流输出的标准输出
stdinfor a stream input
流输入的标准输入
stderrfor printing errors or log messages.
stderr用于打印错误或日志消息。
Each unix program has each one of those streams.
每个 unix 程序都有这些流中的每一个。