Ctrl + D后如何重新启动stdin? [英] How to restart stdin after Ctrl+D?
问题描述
运行需要终端I输入的程序,可以通过Ctrl + D关闭" stdin.之后有什么办法可以重新打开标准输入?
Running a program expecting input from terminal I can "close" stdin by Ctrl+D. Is there any way to reopen stdin after that?
推荐答案
In linux and on POSIXy systems in general, the standard input descriptor is not closed when you press Ctrl+D in the terminal; it just causes the pseudoterminal layer to become readable, with read()
returning 0. This is how POSIXy systems indicate end of input.
这并不意味着文件描述符(甚至C库在其顶部提供的流句柄)都已关闭.正如史蒂夫·萨米特(Steve Summit)在评论中提到的那样,您只需要使用clearerr()
清除流的输入结束状态,便可以读取更多数据.这告诉C库您已经注意到状态变化,但是无论如何都想尝试进一步阅读.
It does not mean the file descriptor (or even the stream handle provided on top of it by the C library) gets closed. As Steve Summit mentioned in a comment, you only need to clear the end-of-input status of the stream using clearerr()
, to be able to read further data; this tells the C library that you noticed the status change, but want to try further reading anyway.
当一个进程正在写入文件,而另一个进程读取它时,可能会发生类似的情况.当阅读器到达文件末尾时,read()
返回0,C库将其理解为输入结束.它设置了一个内部标志,因此,除非您调用clearerr()
,否则feof()
将对该流返回true.现在,如果写者写了更多数据,而读者写了clearerr()
,则读者可以阅读新写的附加数据.
A similar situation can occur when a process is writing to a file, and another reads it. When the reader gets to the end of the file, a read()
returns 0, which the C library understands as end-of-input; it sets an internal flag, so that unless you call clearerr()
, feof()
will return true for that stream. Now, if the writer writes more data, and the reader does a clearerr()
, the reader can read the newly written additional data.
这完全正常,而且是预期的行为.
This is perfectly normal, and expected behaviour.
总结:
-
输入结束由返回0的
read()
操作指示,但文件描述符状态不变,可以正常使用.
End of input is indicated by a
read()
operation returning 0, but the file descriptor status does not change, and can be used as normal.
Ctrl + D 仅导致这种情况发生;向终端打开的文件描述符不会受到任何其他影响,这取决于前台进程读取终端输入以决定其作用.可以继续读取更多数据.
Ctrl+D on a terminal causes only that to happen; the file descriptors open to the terminal are not affected in any other way, and it is up to the foreground process reading the terminal input to decide what it does. It is allowed to simply go on reading more data.
大多数程序都会在发生这种情况时退出,但这只是一个约定,而不是技术要求.
Most programs do exit when that happens, but that is a convention, not a technical requirement at all.
C库检测到read()
返回0,并为该流设置其内部的输入结束"标志.对于该流,这导致feof()
返回true,fgets()
返回NULL,fgetc()
返回EOF
,依此类推.
The C library detects read()
returning 0, and sets its internal "end of input seen" flag for that stream. That causes feof()
to return true, fgets()
to return NULL, fgetc()
to return EOF
, and so on, for that stream.
在流句柄上调用clearerr()
会清除该标志,以便下一次读取尝试实际上将尝试从描述符中读取更多数据.
Calling clearerr()
on the stream handle clears the flag, so that the next read attempt will actually try to read further data from the descriptor.
这在 man 3 clearerr
手册页.
This is described in the very first sentence in the Description section of the man 3 clearerr
man page.
这篇关于Ctrl + D后如何重新启动stdin?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!