Answers:
我为什么要挂断电话
您不会从cat(1)
和获得“挂断” tail(1)
,它们只是阻止读取。 cat(1)
等待输入,并在看到完整的一行时立即打印:
$ cat /dev/stdout
foo
foo
bar
bar
在这里,我输入foo
Enterbar
EnterCTRL- D。
tail(1)
等待输入,仅在可以检测到时才打印EOF
:
$ tail /dev/stdout
foo
bar
foo
bar
在这里我再次输入foo
Enterbar
EnterCTRL- 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
(几乎)所有内容都是文件,但并非所有内容都是常规文件。在特殊文件(例如目录,网络套接字,串行端口等)上调用文本编辑器没有任何意义。
该文件/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
,它会抱怨,因为它不知道如何编辑终端(这根本没有意义)。
cat
并且tail
正在寻找可选内容,然后是文件结尾。/dev/stdout
保持打开状态,所以cat
和tail
公正继续寻找。