Ctrl+D 结束终端行输入

Ctrl+D 结束终端行输入

如果我做

$ cat > file.txt

文本Ctrl- DCtrl-D

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

如果我做

$ cat > file.txt

pa bam pshhh Ctrl-Z

[2]+  Stopped         cat > file.txt
$ cat file.txt
$ cat > file.txt

啪啪啪

Ctrl-Z

[2]+  Stopped         cat > file.txt
$ cat file.txt
pa bam pshhh

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

答案1

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

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

n = read(0, buffer, 512);

需要 512 字节。n是实际读取的字节数,如果出现错误则为 -1。

如果您对普通文件重复执行此操作,您将获得一堆 512 字节的读取,然后在文件尾部读取稍短的内容,如果您尝试读取超过文件末尾,则读取 0。因此,cat将运行直到nis <= 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

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

$ cat > file.txt
pa bam pshhh
<Ctrl+Z>
[2]+  Stopped         cat > file.txt

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

答案2

那是因为Ctrl+D是一个 hack。

在内心深处,Ctrl+ D(尽管被称为eof特点)实际上并不意味着文件结束:它意味着“立即将待处理的输入发送到应用程序”。这实际上接近Ctrl+ M( eol) 的含义,它发送待处理的输入加上换行符。

当您在+后(即在行首)或另一个+后立即按Ctrl+时,待处理的输入为空。因此应用程序接收 0 字节的输入。在一个DCtrlMCtrlDread调用时,读取 0 字节表示文件结束。


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

相关内容