pax*_*blo 221
标准输入 - 这是您的进程读取的文件句柄,以从您那里获取信息.
标准输出 - 您的进程将正常信息写入此文件句柄.
标准错误 - 您的进程将错误信息写入此文件句柄.
这就像我能做到的那样愚蠢:-)
当然,这主要是按照惯例.如果您愿意,没有什么可以阻止您将错误信息写入标准输出.您甚至可以完全关闭三个文件句柄并打开您自己的I/O文件.
当您的进程启动时,它应该已经打开了这些句柄,它只能读取和/或写入它们.
默认情况下,它们可能已连接到您的终端设备(例如/dev/tty
),但是shell会允许您在进程启动之前在这些句柄和特定文件和/或设备(甚至是其他进程的管道)之间建立连接(某些可能的操作相当聪明).
一个例子是:
my_prog <inputfile 2>errorfile | grep XYZ
Run Code Online (Sandbox Code Playgroud)
这将:
my_prog
.inputfile
作为标准输入(文件句柄0).errorfile
作为标准错误(文件句柄2).grep
.my_prog
到标准输入grep
.你的评论:
当我在/ dev文件夹中打开这些文件时,为什么我永远不会看到正在运行的进程的输出?
这是因为它们不是普通文件.虽然UNIX 在某个地方将文件系统中的所有文件都显示为文件,但这并不是最低级别的文件系统./dev
层次结构中的大多数文件都是字符或块设备,实际上是设备驱动程序.它们没有大小,但它们有一个主设备号和次设备号.
当您打开它们时,您已连接到设备驱动程序而不是物理文件,并且设备驱动程序足够聪明,可以知道应单独处理单独的进程.
Linux /proc
文件系统也是如此.这些不是真正的文件,只是严格控制内核信息的网关.
Jim*_*wis 54
这将是更正确的说stdin
,stdout
和stderr
有"I/O流",而不是文件.正如您所注意到的,这些实体并不存在于文件系统中.但就I/O而言,Unix哲学是"一切都是文件".在实践中,真正意味着你可以使用相同的库功能和接口(printf
,
scanf
,read
,write
,select
,等),而不必担心I/O流是否连接到键盘,磁盘文件,插座,管道,或其他一些I/O抽象.
大多数程序需要读取输入,输出写入,并记录错误,所以stdin
,stdout
和stderr
预定义的你,作为一个编程方便.这只是一种约定,并不是由操作系统强制执行的.
Leo*_*ult 40
sar*_*old 22
我担心你的理解是完全倒退的.:)
从程序的角度考虑"标准输入","标准输出"和"标准错误" ,而不是从内核的角度来看.
当程序需要打印输出时,它通常打印到"标准输出".程序通常将输出打印到标准输出printf
,仅打印到标准输出.
当程序需要打印错误信息时(不一定是异常,那些是编程语言结构,强加到更高的级别),它通常会打印到"标准错误".它通常使用fprintf
,它接受打印时使用的文件流.文件流可以是为写入而打开的任何文件:标准输出,标准错误或使用fopen
或打开的任何其他文件fdopen
.
当文件需要读取输入时,使用"标准输入",使用fread
或fgets
,或getchar
.
任何这些文件都可以从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
Run Code Online (Sandbox Code Playgroud)
或者,整个辣酱玉米饼馅:
cat < /etc/passwd > /tmp/out 2> /tmp/err
Run Code Online (Sandbox Code Playgroud)
有两个重要的警告:第一,"标准输入","标准输出"和"标准错误"只是一种惯例.它们是一个非常强大的约定,但它只是一个协议,能够运行这样的程序是非常好的:grep echo /etc/services | awk '{print $2;}' | sort
并且将每个程序的标准输出挂钩到管道中下一个程序的标准输入.
其次,我已经给出了用于处理文件流(FILE *
对象)的标准ISO C函数- 在内核级别,它是所有文件描述符(int
对文件表的引用)和更低级别的操作,如read
和write
,它们不快乐缓冲ISO C功能.我想保持简单并使用更简单的功能,但我认为你应该知道其他选择.:)
通过控制台读取输入(例如键盘输入).在C中使用scanf
scanf(<formatstring>,<pointer to storage> ...);
Run Code Online (Sandbox Code Playgroud)
生成输出到控制台.在C中使用printf
printf(<string>, <values to print> ...);
Run Code Online (Sandbox Code Playgroud)
产生"错误"输出到控制台.在C中使用fprintf
fprintf(stderr, <string>, <values to print> ...);
Run Code Online (Sandbox Code Playgroud)
stdin的源可以重定向.例如,它不是来自键盘输入,而是来自文件(echo < file.txt
)或其他程序(ps | grep <userid>
).
stdout,stderr的目标也可以重定向.例如,stdout可以重定向到文件:ls . > ls-output.txt
在这种情况下,输出将写入文件ls-output.txt
. 标准错误可以重定向用2>
.
我认为有人说stderr
只应将错误消息用于误导。
它也应该用于提供给运行该命令的用户的信息性消息,而不是给数据的任何潜在下游使用者(例如,如果您运行将多个命令链接在一起的Shell管道,则您不希望获得诸如“获取第30条信息”之类的信息性消息)。 42424“出现在屏幕上,stdout
因为它们会使消费者感到困惑,但是您可能仍希望用户看到它们。
见这个历史的理由:
“所有程序都会对标准输出进行诊断。这总是在将输出重定向到文件时引起麻烦,但是在将输出发送到毫无疑问的过程时变得无法忍受。尽管如此,不愿意违反标准输入的简单性在标准输出模型中,人们通过v6容忍了这种情况,此后不久,丹尼斯·里奇(Dennis Ritchie)通过引入标准错误文件削减了戈尔迪诺结,这还远远不够,利用管道诊断可以来自多个同时运行的程序。诊断程序需要识别自己。”
小智 5
使用 ps -aux 显示当前进程,所有进程都在 /proc/ 中列为 /proc/(pid)/,通过调用 cat /proc/(pid)/fd/0 它会打印在标准输出中找到的任何内容我认为这个过程。所以也许,
/proc/(pid)/fd/0 - 标准输出文件
/proc/(pid)/fd/1 - 标准输入文件
/proc/(pid)/fd/2 - 标准错误文件
例如
但只对 /bin/bash 有效,其他进程通常在 0 中没有任何内容,但许多在 2 中写入了错误
归档时间: |
|
查看次数: |
231841 次 |
最近记录: |