您的位置:首页 > 其它

Per笔记:10、文件测试

2013-10-14 12:54 337 查看

一、文件测试操作符及其意义:

-r 文件或目录,对目前(有效地)用户或组来说是可读的

-w 文件或目录,对目前(有效地)用户或组来说是可写的

-x 文件或目录,对目前(有效地)用户或组来说是可执行的

-o 文件或目录,由目前(有效的)用户拥有

-R 文件或目录,对实际的用户或组来说是可读的

-W 文件或目录,对实际的用户或组来说是可写的

-X 文件或目录,对实际的用户或组来说是可执行的

-O 文件或目录,由实际的用户拥有

-e 文件或目录,是存在的

-z 文件存在而且没有内容(对目录来说永远为假)

-s 文件或目录存在并且有内容(返回值是以字节为单位的文件大小)

-f 是普通文件

-d 是目录

-l 是符号链接

-S 是socket类型的文件

-p 是命名管道,也就是先入先出(fifo)队列

-b 是块设备文件(如某个可挂载的磁盘)

-c 是字符设备文件(如某个I/O设备)

-u 文件或目录设置了setuid位

-g 文件或目录设置了setgid位

-k 文件或目录设置了sticky位

-t 文件句柄是TTY设备

-T 看起来想文本文件

-B 看起来是二进制文件

-M 最后一次修改后至今的天数

-A 最后一次访问后至今的天数

-C 最后一次文件节点编号(inode)变更后至今的天数

二、同一文件多个测试属性

一般两个测试属性可以用and操作符来连接:

if ( -r $file and -w $file){

...

}

实际上这样的写法是比较浪费资源的,通常情况下可以写成如下的简写方式:

if ( -r $file and -w _ ) {

...

}

注意:这里使用下划线(_)
来代替文件名,这是因为我前面已经用-r测试操作符对$file进行了测试,当第二次测试同一个文件的时候可以使用这种简写方式,当然第三次,第四次也可以使用,但一定是没有另一个文件测试之前。否则就变成了上一个测试的文件了。多说无益,看看下面的例子:

if( -r
$file ) {

print "The
file is readable!\n";

}

lookup( $other_file );

if( -w _
) {

print "The
file is writable!\n";

}

sub lookup
{

return -w
$_[0];

}

像上例的情况,-w测试的文件就不是$file,而是$other_file

三、栈式文件测试操作

Perl5.10 以后的版本支持这种写法

use
5.010;

if( -r
-w -x -o
-d $file )
{

print "dir
is readable, writable, and executable!\n";

}

注意:对于返回真假值以外的测试来说,栈式写法并不出色。如下面的例子,我本意想确认小于512字节的目录,但实际上没有做到:

use
5.010;

if( -s -d $file < 512)
{ # 注意,不要这样写

print "The
directory is less than 512 bytes!\n";

}

上面的可以展开写成如下的格式:

if( (
-d $file and -s _ ) < 512 )
{

print "The
directory is less than 512 bytes!\n";

}

当-d返回假时,Perl将假值同数字512作比较。比较的结果变为真,因为假等效于数字0,而0永远小于512,为了避免这种问题,还是写成分开的方式比较好:

if( -d
$file and -s _ < 512 )
{

print "The
directory is less than 512 bytes!\n";

}

四、stat和lstat函数

这两个函数会测试 文件或目录,然后返回一个含有13个元素的列表,详细信息如下:

my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev,

$size, $atime, $mtime, $ctime, $blksize, $blocks)

= stat($filename);

对符号链接符调用stat函数的话,会返回符号连接指向的文件信息,如果要返回符号连接的信息请使用lstat函数

五、localtime函数

前文的stat函数中返回的atime,mtime,ctime的格式类似于1272349300这样的值,该值是从1900年至现在的秒数,可以利用locattime函数将该值格式化一下:

#!/usr/bin/perl
-w

use
strict;

my $file=$ARGV[0];

my($dev,
$ino, $mode,
$nlink, $uid,
$gid, $rdev,

$size, $atime,
$mtime, $ctime,
$blksize, $blocks)

= stat($file);

my($sec,
$min, $hour,
$day, $mon,
$year,

$wday, $yday,
$isdst) =
localtime $atime;

print "$ARGV[0] atime is :$atime\n";

$year+=1900;

print "$ARGV[0] localtime atime is :$year\n";

执行# perl localtime.pl /etc/passwd

后输出结果为:

/etc/passwd atime is :1272349801

/etc/passwd localtime atime is :2010

由于localtime函数获得的year也是1900年到现在经过的年数,因此,要得到现在的年应该加1900。

$wday 代表今天是本周的第几天,0为周日3为周三

$yday 代表今天是今年的第几天,范围是 0..364 (或 0..365 闰年.)

此外还有2个有用的函数:

gmtime 返回世界标准时间

time 从系统时钟取得时间戳

=================本章习题===================

1、写一程序,从命令行取得文件名,并汇报这些文件是否可读、可写、可执行以及是否的确存在。程序可以支持一次传送多个要测试属性的文件。

#!/usr/bin/perl
-w

use
strict;

foreach my $file (@ARGV){

if (!
-e $file){

print "$file not exists!\n";

last;

}

-r $file?print "$file is readable!\n"

:print "$file not readable!\n";

-w $file?print "$file is writeable!\n"

:print "$file not writeable!\n";

-x $file?print "$file is executable!\n"

:print "$file not executable!\n";

-o $file?print "$file is owned by this user!\n"

:print "$file not owned by this user!\n";

}

2、编写程序,从命令行参数指定的文件中找出最旧的文件并且以天数汇报它存在了多久,若命令行参数为空程序改如何处理?

#!/usr/bin/perl
-w

use
strict;

die "No
file names supplied!\n" unless @ARGV;

my $old_file = shift @ARGV;

my $old_age = -M
$old_file;

foreach (@ARGV){

my $age =
-M;

($old_file,$old_age) =
($_,$age)
if

$age>$old_age;

}

printf "the oldest file is
%s,and it was %.1f days old\n",$old_file,$old_age;

执行:perl ex_2.pl /etc/*

输出结果:

the oldest file is /etc/hosts.allow,and it was 3757.4 days old
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: