进一步阅读

进一步阅读

我有以下两个测试文件:

test1 test2

两者都是空白。现在我发出以下命令:

$ cat > test1  

Enter

This is a test file

Enter

Ctrl+D

$ cat > test2

Enter

This is another test file

Enter

^C

Ctrl+C

$

现在我检查两个文件的内容

$ cat test1
This is a test file
$ cat test2
This is another test file
$

那么,如果我们使用上述两种方法来达到相同的结果,结果有什么真正的区别吗?

答案1

cat命令运行时,终端处于规范输入模式。简而言之,这意味着终端的线路纪律正在处理行编辑,并响应所有特殊字符为终端配置(可通过命令查看和设置stty)。

cat命令只是read()从其标准输入中进行 ing,直到read()调用返回读取的零字节(这是命中文件末尾的 POSIX 约定)。

终端并没有真正的“终点”。但存在read()终端设备返回零字节的情况。当线路规则收到“EOF”特殊字符时,无论当时配置了什么,它都会导致read()返回当时编辑缓冲区中的任何内容。如果编辑缓冲区为空,则返回从 读取的零字节read(),导致cat退出。

cat也退出以响应其默认操作是终止进程的信号。线路规则还生成响应特殊字符的信号。 “INTR”和“QUIT”特殊字符导致INTQUIT信号被发送到前台进程(组),该进程将是/包含该cat进程。这些信号的默认操作是终止进程cat

这导致了可观察到的差异:

  • Ctrl+D仅当它是 EOT 特殊字符时才有此动作。这是通常情况如此,但事实并非如此一定案子。同样,Ctrl+C只有当它是INTR特殊字符时才起作用。
  • Ctrl当该行当时实际上不为空时,+D不会导致终止。不过, +会cat产生中断。CtrlC
  • cat如果发现缓冲区标准输出指向文件,则 C 语言中的简单实现将阻止缓冲区标准输出,如问题中所示。理论上,如果cat由 终止,这可能会导致缓冲但尚未输出的行丢失SIGINT

    实际上,BSD 和 GNU C 库实现了 C 或 C++ 语言标准中未描述的缓冲模式。重定向到文件或管道时的标准输出是智能缓冲。它是块缓冲的;除了每当 C 库发现自己即将read()从向终端设备打开的任何文件描述符开始新行时,它都会刷新标准输出。 (严格来说,BSD 和 GNU C 库并不完全实现相同的语义,而且做的事情还不止于此,但这种行为是一个常见的子集。)因此,当中断信号cat构建在这样的之上时,不会导致丢失缓冲输出。C 库。

  • 当然,如果cat是命令管道的一部分,有些其他cat在这些数据到达输出文件之前,进程可以在下游缓冲数据。因此,当线路规则发送SIGINT(默认情况下)终止管道中的所有进程时,缓冲且尚未写入的输入数据将丢失;而cat使用“EOF”特殊字符正常终止将导致管道正常终止,所有数据之前都会传递到下游进程收到 EOF 指示它是 read()其标准输入。

请注意,这与交互式 shell 读取您的一行输入时发生的情况关系不大。当你的 shell 等待输入时,终端处于非规范输入模式,在哪种模式下线路纪律不做对特殊字符的任何特殊处理。 shell 如何处理Ctrl+DCtrl+C完全取决于 shell 使用的输入编辑库(libedit、readline 或 ZLE)以及该编辑库的配置方式(使用键绑定等)。

进一步阅读

答案2

CTRL+C 是中断信号。它将停止该命令。

CTRL+D是文件结尾或exit().当您输入CTRL+时D,它因文件结尾而退出命令。如果你在 shell 中输入CTRL+ ,什么也不会发生。C但是,如果您输入CTRl+ D,它将从大多数系统中当前的 Shell 中退出。

相关内容