Ctrl+D 结束终端行输入

mis*_*ist 23 command-line terminal cat

如果我做

$ cat > file.txt
Run Code Online (Sandbox Code Playgroud)

文本Ctrl- DCtrl-D

问题 1:如果我不按 Enter,为什么我必须按Ctrl-D两次?

如果我做

$ cat > file.txt
Run Code Online (Sandbox Code Playgroud)

pa bam pshhh Ctrl-Z

[2]+  Stopped         cat > file.txt
$ cat file.txt
$ cat > file.txt
Run Code Online (Sandbox Code Playgroud)

pa bam pshhh

Ctrl——Z

[2]+  Stopped         cat > file.txt
$ cat file.txt
pa bam pshhh
Run Code Online (Sandbox Code Playgroud)

为什么第二次是 1 行的文件?

Mar*_*ick 34

在 Unix 中,您可以读写的大多数对象——普通文件、管道、终端、原始磁盘驱动器——都被制作成类似于文件。

像这样的程序cat从它的标准输入中读取:

n = read(0, buffer, 512);
Run Code Online (Sandbox Code Playgroud)

它要求 512 个字节。n是实际读取的字节数,如果有错误,则为 -1。

如果你对一个普通文件重复这样做,你会得到一堆 512 字节的读取,然后在文件的尾端读取稍微短一些,如果你试图越过文件的末尾读取,则为 0。因此,cat将运行直到n<= 0。

从终端读取略有不同。键入一行后,由Enter键终止,read仅返回该行。

您可以键入一些特殊字符。一个是Ctrl-D。当您键入此内容时,操作系统会将您键入的所有当前行(但不是其Ctrl-D本身)发送给执行读取的程序。这是一个偶然的事情:如果Ctrl-D是该行的第一个字符,则向程序发送长度为 0 的行 - 就像程序会查看它是否刚刚到达普通文件的末尾一样。cat 不需要做任何不同的事情,无论是从普通文件还是终端读取。

另一个特殊字符是Ctrl-Z. 当您在一行中的任何位置键入它时,操作系统会丢弃您在该点之前键入的任何内容,并向程序发送 SIGTSTP 信号,程序通常会停止(暂停)它并将控制权返回给 shell。

所以在你的例子中

$ cat > file.txt
pa bam pshhh<Ctrl+Z>
[2]+  Stopped         cat > file.txt
Run Code Online (Sandbox Code Playgroud)

您输入了一些被丢弃的字符,然后cat在没有向其输出文件写入任何内容的情况下停止。

$ cat > file.txt
pa bam pshhh
<Ctrl+Z>
[2]+  Stopped         cat > file.txt
Run Code Online (Sandbox Code Playgroud)

您输入了一行,cat读取并写入其输出文件,然后Ctrl-Z停止cat.

  • 这些事情仅适用于[规范模式终端](http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap11.html)。即使在这种情况下,它们也可以改变。 (2认同)

Gil*_*il' 21

那是因为Ctrl+D是一个黑客。

在内心深处,Ctrl+ D(尽管被称为eof字符)实际上并不意味着文件结束:它的意思是“现在将待处理的输入发送到应用程序”。这其实和Ctrl+ M( eol)的意思很接近,就是发送pending input加上一个换行符。

当您按下Ctrl+D一后立即Ctrl+ M(即在一行的开头)或陆续Ctrl+ D,待定输入为空。因此,应用程序接收 0 字节的输入。在read调用中,读取 0 字节表示文件结束。


当您按Ctrl+ 时Z,将丢弃待处理的输入。因此,只有在按+之前cat通过输入换行符或Ctrl+已发送到应用程序的内容(即)D才会被处理。CtrlZ