我正在谈论这个:
$ readlink <(echo test)
pipe:[80076194]
是pipe:[80076194]
目标的路径还是仅指示文件描述符已连接到管道并且文件系统中不存在?我问的主要原因是由于php
有人试图取消引用它:
$ strace -f php -r 'var_dump(file_get_contents($_SERVER["argv"][1]));' -- <(echo test)
...
[pid 654] lstat("/dev/fd/63", {st_mode=S_IFLNK|0500, st_size=64, ...}) = 0
[pid 654] readlink("/dev/fd/63", "pipe:[80095114]", 4096) = 15
[pid 654] lstat("/dev/fd/pipe:[80095114]", 0x7fff9c3628a0) = -1 ENOENT (No such file or directory)
[pid 654] lstat("/dev/fd", {st_mode=S_IFLNK|0777, st_size=13, ...}) = 0
[pid 654] readlink("/dev/fd", "/proc/self/fd"..., 4096) = 13
[pid 654] lstat("/proc/self/fd", {st_mode=S_IFDIR|0500, st_size=0, ...}) = 0
[pid 654] lstat("/proc/self", {st_mode=S_IFLNK|0777, st_size=64, ...}) = 0
[pid 654] readlink("/proc/self", "654"..., 4096) = 3
[pid 654] lstat("/proc/654", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
[pid 654] lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
[pid 654] open("/proc/654/fd/pipe:[80095114]", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 654] write(2, "PHP Warning: file_get_contents("..., 125PHP Warning: file_get_contents(/dev/fd/63): failed to open stream: No such file or directory in Command line code on line 1
) = 125
[pid 654] write(1, "bool(false)\n", 12bool(false)
) = 12
答案1
简而言之,不,它不存在。
长:
Linux 中有两种类型的管道,命名管道(又名 fifo)和匿名管道。
命名管道是通过mkfifo
( man 3 mkfifo
) 系统调用创建的。命名管道作为文件存在于文件系统上。一个进程打开它进行读取,另一个进程打开它进行写入。
匿名管道是通过pipe
( man 2 pipe
) 系统调用创建的。一旦打开,它们的行为与打开 mkfifo 管道完全相同。它们占用一个文件描述符,一端开放用于读取,另一端开放用于写入。
因为它们占用文件描述符,所以它们显示在/proc/PID/fd/
.但由于它们在任何地方都不作为实际文件存在,因此 in 中的条目/proc/PID/fd/
必须发挥一些作用。所以基本上管道被表示为带有虚假目标的符号链接。当您打开符号链接时,内核实际上打开了符号链接表示的管道。但由于它是一个符号链接,并且符号链接有目标,任何尝试取消引用符号链接(不是通过内核隐式)的操作都会返回一个目标。只是这个目标没有指向有效的文件。
通常您不能使用符号链接来执行此操作,但是该/proc
文件系统不是普通的文件系统。这是一个由内核代表的假文件系统。由于内容是由内核创建的,因此内核可以打破自己的规则。