从下面的消息中,我们知道文件/ proc / sys / net / ipv4 / ip_forward中有两个字符,但为什么ls只是显示这个文件的大小为零?
我知道这不是磁盘上的文件,而是内存中的文件,所以有没有命令可以看到/ proc中文件的实际大小?
root@OpenWrt:/proc/sys/net/ipv4# cat ip_forward | wc -c
2
root@OpenWrt:/proc/sys/net/ipv4# ls -l ip_forward
-rw-r--r-- 1 root root 0 Sep 3 00:20 ip_forward
root@OpenWrt:/proc/sys/net/ipv4# pwd
/proc/sys/net/ipv4
那些不是磁盘上的真正文件(正如你所提到的)但它们也不是内存中的文件 - / proc中的名称对应于对操作系统中正在运行的内核的调用,并且内容是动态生成的。
系统在不生成文件的情况下不知道文件的大小,但如果您两次读取“文件”,则无法保证您获得相同的数据,因为系统可能已更改。
您可能正在寻找程序sysctl -a。
/ proc中的东西不是真正的文件。在大多数情况下,它们甚至不是内存中的文件。当您访问这些文件时,proc文件系统驱动程序执行系统调用,该系统调用获取适合该文件的数据,然后将其格式化以进行输出。这通常是动态构建的动态数据。一个例子是/ proc / net / arp,它包含当前的ARP缓存。
获取这些东西的大小只能通过格式化整个输出来完成,因此在列出文件时不会这样做。如果你想要尺寸,请像你一样使用wc -c
。
/proc/
文件系统是由内核维护的“错觉”,它不会给出(大部分)其伪文件的大小(因为计算“真实”大小通常涉及构建整个文本伪文件的内容)并且期望来自/proc/
的大多数[伪]文本文件在合理大小(例如1K)的块中从第一个到最后一个字节(即直到EOF)依次读取。有关详细信息,请参见proc(5)手册页。
所以没有办法在单个系统调用中获得真实大小(像/proc/self/maps
或/proc/sys/net/ipv4/ip_forward
这样的文件)(比如stat(2),因为它的大小为0,正如stat(1)或ls(1)命令所报告的那样)。阅读这些文本文件的典型方法可能是
FILE* f = fopen("/proc/self/maps", "r");
// or some other textual /proc file,
// e.g. /proc/sys/net/ipv4/ip_forward
if (f)
{
do {
// you could use readline instead of fgets
char line[256];
memset (line, 0, sizeof(line));
if (NULL == fgets(line, sizeof(line), f))
break;
// do something with line, for example:
fputs(line, stdout);
} while (!feof (f));
fclose (f);
}
当然,一些文件(例如/proc/self/cmdline
)被记录为可能包含NUL字节。你需要一些fread
。
它不是内存中的文件,它是用户和内核之间的接口。