为什么不能使用文本编辑器读取/ dev / stdout?


9

我刚刚开始学习Linux上的“ 什么都是文件TM ”,这使我想知道如果我从/ dev / stdout中逐字读取,会发生什么:

$ cat /dev/stdout 
^C
$ tail /dev/stdout 
^C

(这^C是我在程序挂起后将其杀死)。

当尝试使用时vim,出现了无法想象的消息:“ / dev / stdout”不是文件。喘气!

那么,当尝试读取这些“文件”时,为什么会出现挂断或错误消息呢?


1
vim认为文件与* nix中的“一切都是文件”(无关联商标)的含义不是同一回事。参见例如#1#2
goldilocks 2015年

Answers:


11

我为什么要挂断电话

您不会从cat(1)和获得“挂断” tail(1),它们只是阻止读取。 cat(1)等待输入,并在看到完整的一行时立即打印:

$ cat /dev/stdout
foo
foo
bar
bar

在这里,我输入fooEnterbarEnterCTRL- D

tail(1)等待输入,仅在可以检测到时才打印EOF

$ tail /dev/stdout
foo
bar
foo
bar

在这里我再次输入fooEnterbarEnterCTRL- D

或错误消息

Vim是唯一一个出错的代码。它确实是因为它运行的 stat(2)反对/dev/stdout,和它发现它不具备S_IFREG位设置。

/dev/stdout是文件,但不是常规文件。实际上,内核中有一些舞步可以在文件系统中提供一个入口。在Linux上:

$ ls -l /dev/stdout
lrwxrwxrwx 1 root root 15 May  8 19:42 /dev/stdout -> /proc/self/fd/1

在OpenBSD上:

$ ls -l /dev/stdout
crw-rw-rw-  1 root  wheel   22,   1 May  7 09:05:03 2015 /dev/stdout

在FreeBSD上:

$ ls -l /dev/stdout
lrwxr-xr-x  1 root  wheel  4 May  8 21:35 /dev/stdout -> fd/1

$ ls -l /dev/fd/1
crw-rw-rw-  1 root  wheel  0x18 May  8 21:35 /dev/fd/1

5

(几乎)所有内容都是文件,但并非所有内容都是常规文件。在特殊文件(例如目录,网络套接字,串行端口等)上调用文本编辑器没有任何意义。

该文件/dev/stdout可以是以下几种之一,具体取决于unix变体:

  • “特殊”文件,通常是字符设备;
  • 一个“魔术”符号链接,指向正在访问该文件的进程已在此描述符上打开的文件;
  • 指向上述之一的符号链接。

在任何情况下,打开/dev/stdout文件和类似文件都会创建一个新文件描述符,该文件描述符与应用程序在文件描述符1上已经打开过的同一文件相关联。“标准输出”表示文件描述符1,仅使用此文件描述符是一个惯例。输出-内核不在乎。

在终端中运行程序时,将在终端设备上打开所有三个标准描述符(0 =标准输入,1 =标准输出,2 =标准错误)。从该设备读取将返回用户键入的字符,而对该设备进行写入则会在终端窗口中显示文本。(对于终端设备,没有标准方法可以读取其显示的输出或将输入注入其中。)

运行时cat /dev/stdout,它与cat /dev/stdin或完全相同cat /dev/stderr,因为这三个文件描述符连接到同一文件:它指示cat从终端读取。那也是cat没有参数的事情。

如果您运行cat /dev/stdout >foo/dev/stdout则将引用该文件foo-该命令等效于cat foo >foo。根据cat实现的不同,它可能会出错(GNU版本抱怨“输入文件就是输出文件”),或者可能什么都不做,因为它从foo空文件中读取(>foo被截断了)。使用该版本cat不会检测到这种特殊情况,如果foo不为空,则cat /dev/stdout >>foo或等效项cat foo >>foo将无限期地将文件内容附加到其自身。

当您运行时vim /dev/stdout,它会抱怨,因为它不知道如何编辑终端(这根本没有意义)。


2

cat并且tail正在寻找可选内容,然后是文件结尾。/dev/stdout保持打开状态,所以cattail公正继续寻找。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.