1.文件测试操作符:
-r 文件或目录,对目前用户来说是可读
-w 文件或目录,对目前用户来说是可写
-x 文件或目录,对目前用户来说是执行
-o 文件或目录,对目前用户拥有
-R 文件或目录,对实际用户或组来说是可读
-W 文件或目录,对实际用户或组来说是可写
-X 文件或目录,对实际用户或组来说是可执行
-O 文件或目录,是由实际的用户拥有
1.1.测试同一文件的多项属性:
if(-r $file and -w $file)
{....} #这样非常耗费资源的操作,每次进行文件测试时,perl都得从文件系统中取出所有的相关信息。
使用虚拟文件句柄(_)避免重复性操作:
if( -r $file and -w _){...}
连续在多个文件语句中使用虚拟句柄:
if(-r $file)
{
print "True1\n";
}
if( -w _)
{
print "True2\n";
}
这么用的时就有一个问题,必须清楚代码最后一次查询的否同一个文件。若是在两个文件测试之间,
又被调用了某个子程序,那么最后一个查询的文件可能会变化。
比如说,下面的例子调用了lookup子程序,在其内部对另一个文件做了一次测试。当子程序返回后,
再执行文件测试时,文件句柄_代表的就是一原先的$file,而是$other_file
if( -r $file)
{
print "$file is readable\n";
}
lookup($other_file);
if( -w _)
{
"The file is writeable\n";
}
sub lookup
{
return -w $_[0];
}
1.2.栈式文件测试操作符:
if( -w -r $file)
{
"The file is writeable and readable\n";
}
if( -w -r -x -o -d $file)
{.....}
if((-d $file and -s _) < 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";
}
-e 文件或目录 是存在的
-z 文件存在而且是没内容的
-s 文件或目录存在而且有内容(反回值是以字节为单位的文件大小)
UNINX系统上有7种文件类型:
-f 是普通文件
-d 是目录
-l 是符号链接
-S 是SOCKET类型文件
-p 是命名管道,也就是先入先出(fifo)队列
-b 是块设备文件(如某个可挂载的磁盘)
-c 是字符设备文件(比如某个I/O设备)
-u 文件或目录设置了setuid位
-g 文件或目录设置了setgid位
-k 文件或目录设置了sticky位
-t 文件句柄是TTY设备
-T 看起像文本文件
-B 看起来像二进制文件
文件时间测试操作:分别会返回该文件最后一次被修改,被访问或者其他的indoe实变更
后到现在的天数,indoe是文件系统的索引条目,其中记录了某个文件的所有属性信息,但
文件内容除外,相关细节可以参考系统函数stat的文档。
-M 最后一次修改后至今的天数
-A 最后一次访问至今的天数
-C 最后一次文件节点编号被变更后至今的天数
2.stat 和 lstat 函数
my($dev,$ino,$mode,$nlink,$uid,$gid,$dev,$size,$atime,$mtime,$ctime,$blksize,$blocks)=stat($filename)
$dev和$ino
即文件设备所在设备编号与文件的inode编号。
$mode
文件的权限位集合,还包含其他信息位
$nlink
文件或目录的(硬链接),也就是这个目录有多个真实名称。
$uid $gid
以数值形式表示文件拥有者的用户ID和组ID
$size
以字节为单位的文件大小,和-s文件测试操作返回值相同
$atime,$mtime,$ctime
三种时间戳,但这里以系统时间格式来表示,一个32位的整数,表示从纪元(epoch)算起的秒数,
纪元是测量系统时间的任意基点
3.localtime函数:
my($sec,$min,$hour,$day,$mon,$year,$wady,$yday,$isdst)=locatime();
$mon范围是0到11月份
$year是一个自1900年起算的年数,所以将这值加上1900就是实际年份。
$day范围是0到6
$ydat则表示目前今年的第几天0(1月1日)到364或365(12月31日)
目录操作:
1.在目录树中移动
chdir '/etc' #改变当前工作目录
2.文件名通配
一般来说,shell命令行里的文件名模式展开所有匹配的文件名。这叫称为通配(glob).
比如把*.rpm文件名模式交给echo命令,shell会将它展开名称相匹配的文件列表:
echo .rpm
test1.rpm test2.rpm test3.rpm test.rpm
对perl来说也是一样:
foreach $args(@ARGV)
{
print "One arg is $agrs\n";
}
在内部还可用glob操作符来匹配:
my @rpms = glob '*.rpm'; #取得当前目录的所有文件并按字母顺序排序
3.文件通配的另一种方法:
my @rpm=<*.rpm>; # or my @path = <*>;
my @all_file=<*> ;#效果和这样写法的完全一致my @all_file= glob '*';
readline操作符执行间接读取文件句柄:
my @lines = readline FRED;
3.目录句柄:
opendir #打开目录句柄
readdir #读取目录句柄
my $dir = '/etc';
opendir(DR,$dir) or die "Cant open $dir:$!\n";
while(my $name = readdir DR)
{
next if $name =~/\.|\.\./;
print "One file in $dir is $name\n";
}
closedir(DR);
4.递归访问目录:
这里使用的是File::Find,可以去查看文档perldoc File::Find的用法。不在具体介绍。
5.文件和目录的操作
5.1.删除文件:
unlink #删除操作符
unlink 'test1','test2','test3'; #删除多个文件
unlink qw(test1 test2 test3) ; #同上
或
unlink glob '*.txt' #删除后缀为.txt的所有文件
5.2.重命名文件
rename 'oldname','newname';
rename './test.rpm','new.rpm';
foreach my $file(glob '*.old')
{
my $newfile=$file;
$newfile =~s/\.old/.new/;
if( -e $newfile)
{
warn "Cant rename $file to $newfile:$newfile exists\n";
}
elsif(rename $file=>$newfile)
{
;
}
else
{
warn "Rename $file to $newfile failed:$!\n";
}
}
6.链接与文件
硬链接:(实体链接)
硬链接则透过文件系统的inode来产生新档名,而不是产生新档案。
inode:
要解释清楚两者的区别和联系需要先说清楚 linux 文件系统中的 inode 这个东西。当划分磁盘分区并格式化的时候
,整个分区会被划分为两个部分,即inode区和data block(实际数据放置在数据区域中)这个inode即是(目录、档案)
文件在一个文件系统中的唯一标识,需要访问这个文件的时候必须先找到并读取这个文件的 inode。
Inode 里面存储了文件的很多重要参数,其中唯一标识称作 Inumber, 其他信息还有创建时间(ctime)、
修改时间(mtime) 、文件大小、属主、归属的用户组、读写权限、数据所在block号等信息。
目录文件与档案文件
目录文件:记录该目录下的文件名
档案文件:记录实际文件数据
inode本身并不记录文件名,文件名记录在目录文件的block当中,所以新增、删除、更改文件名与目录的W权限有关。
因此当我们要读某个档案时,就务必经过其目录的inode和block,然后才能够找到待读取档案的inode号,
最终才会读到正确的档案block内的数据。系统是通过索引节点(而不是文件名)来定位每一个文件。
目录inode(满足权限?) => 目录block => 档案inode(满足权限?) => 档案block
多个档名对应同一个inode,硬链接只是在某个目录下新增一笔档名链接到某个inode号码的关联记录而已.
link 'test1.rpm','nlink.rpm' or warn "Cant link test1.rpm to nlink.rpm:$!\n";
符号链接(symbolic link).
符号链接也叫软件链接(soft link)。
symlink 'test','newlink' or warn "Cant link test to newlink:$!\n";
取得链接符号指向位置:
readlink 函数,它会返回符号链接指向的位置。
my $where = readlink 'newlink'
print "$where\n";
7.创建和删除目录
mkdir 'test' 0755 or warn "Cant make test directory:$!\n";
my $name = 'test';
my $permissions ="0755"; #危险,0755被当成十进制处理,解决方案:oct()函数,转换成八进制来处理
mkdir $name,$permissions;
mkdir $name,oct($permissions);
删除目录(如果目录不是空目录不能删除目录,所要先清空目录,然后删除)
unlink glob './test/*';
rmdir 'test';
8.修改权限
chmod 0755,'test','test2';
chmod 0755,glob '*';
9.修改隶属关系:
my $user = 500; #只支持ID号
my $group =500;
chown $user,$group, glob '*.txt';
defined(my $user=getpwnam 'mysql') or die 'bad user';
defined(my $group=getpwnam 'mysql') or die 'bad group';
chown $user,$group, '*.txt';
10.修改时间戳
my $now = time;
my $age = now - 24*60*60;
utime $now,$ago,glob '*';
小结:本章节主介绍了文件测试的操操作符,七种文件类型;
文件属性函数stat,lstat和时间函数localtime();
通配文件名glob函数使用方法;
文件重命名(rename)和创建硬链接和软件连接的方法(link,symlink);
文件和目录的操作,包含创建,删除,修改隶属,修改权限,修改时间戳
文件测试和目录操作
最新推荐文章于 2022-12-02 08:35:37 发布