【发布时间】:2016-11-02 04:49:31
【问题描述】:
我正在尝试使用 perl 解析来自/proc 和/sys linux 伪文件系统(procfs 和sysfs)的一些伪文件。此类文件与常规文件不同 - 它们由自定义文件操作处理程序实现。其中大多数stat 的大小为零,有些无法打开以供读取,有些则无法写入。有时它们实现不正确(这是错误,但它已经在内核中),我仍然想直接从 perl 中读取它们而不启动一些帮助工具。
有一个用perl读取/proc/loadavg的简单例子,这个文件是正确实现的:
perl -e 'open F,"</proc/loadavg"; $_=<F>; print '
使用strace 的命令我可以检查perl 如何实现open 函数:
$ strace perl -e 'open F,"</proc/loadavg"; $_=<F>; print ' 2>&1 | egrep -A5 ^open.*loadavg
open("/proc/loadavg", O_RDONLY) = 3
ioctl(...something strange...) = -1 ENOTTY
lseek(3, 0, SEEK_CUR) = 0
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
fcntl(3, F_SETFD, FD_CLOEXEC) = 0
open perl 函数使用了lseek 系统调用。
cat /proc/loadavg 的 strace 没有额外的 seek 类型的系统调用:
$ strace cat /proc/loadavg 2>&1 | egrep -A2 ^open.*loadavg
open("/proc/loadavg", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
我要读取(或写入)的特殊文件错误地实现了seek 文件操作,并且在seek 之后不会向read(或write)系统调用提供任何有用的数据。
有没有办法在不调用额外lseek 的情况下打开文件以在 perl5(无外部模块)中读取? (并且不使用system("cat < /proc/loadavg"))
有没有办法在不调用额外的lseek 的情况下打开文件以在 perl5 中写入?
有 sysopen,但也有额外的 lseek:perl -e 'use Fcntl;sysopen(F,"/proc/loadavg",O_RDONLY);sysread(F,$_,2048); print '
【问题讨论】:
-
在我尝试过的 linux 机器上,
open F, "<:unix", "/proc/loadavg"只执行fstat并在 exec 上设置关闭 -
@ikegami,你的回答中使用了什么样的黑魔法(
<:unix)(文档或源链接可能有用)?它也没有在我的测试 linux 上搜索。 -
签出
perl -MPerlIO -E'open F, "<", $ARGV[0] or die $!; say for PerlIO::get_layers(\*F);' ~/.bashrc,然后再次尝试指定:unix。 -
@ikegame,还有
fstat和my $SET,">:unix",".../driver_command; print $SET $COMMAND."\n"; close $SET;我可以禁用它吗?我的脚本仍然无法与驱动程序通信;但普通的echo SAME_COMMAND > .../driver_command有效,我在这里只看到额外的 fstat。
标签: linux perl file-io seek procfs