首先说明一下实现的功能:(Linux环境)指定一个路径,将该路径下的所有文件或者文件夹进行删除。
为了简单起见,这里指定的路径为全路径,不能使用相对路径。对于如何获取全路径实现方式有很多,这里不再 介绍。
本文主要分为以下几个部分
1)获取目录下文件的方法
2)为什么不能使用rm -rf的方式
3)perl的代码实现
获取目录下文件的方法
在提供解决方法之前,首先介绍一下perl来获取目录下文件方法。
方法一:使用句柄的方式
my $dir_name = "/home/usrer/documents";
opendir(DIR, $dir_name) || die "Can't open directory $dir_name";
my @dots = readdir(DIR);
foreach (@dots){
print;
print "/n";
}
closedir DIR;
–这种方法得到的是相对路径下的文件名。如果需要对文件进行深入处理,比如读取文件内容等操作,还需要组合获取全路径。
方法二: 使用glob操作
my @files=glob("/home/usrer/documents/*");
foreach (@files) {
print;
print "\n";
}
–glob所获得获取目录中的所有文件(以及文件夹)并按字母顺序排序,但不包括以点号开头的文件。也就是说这种方法并不能获取隐藏文件。
–这种方式获得的文件或者文件夹是全路径文件和目录名,通常进行下不需要再进行组合获取全路径,可以直接进行其它处理
为什么不能使用rm -rf的方式
有人提出为什么不能使用system(“rm -rf dir_name”);的方式来实现?这样岂不是很简单?
对于手动方式进行处理,使用rm -rf方式的确很方便,但是在脚本中使用这种方式需要保证$dir_name为期望的值,不能是根目录“/”或者其它目录。在脚本处理中如何判断目录的有效性并不是一个简单的事情。期望的路径为“a/b/c”,怎么判断路径不是a或者a/b,甚至是a/c?在复制的情况下这种判断方式也不一定通用。
我们认为使用rm -rf方式的操作不是安全的。
perl的代码实现
代码实现如下
use strict;
use warnings;
use autodie;
use File::Spec;
my $log_file = File::Spec->catfile("/home/operation", "logs/recover_operation.log");
open(LOG_FILENAME, '>', "$log_file");
my $target_directory = "/tmp";
&delete_all_files_under_path($target_directory);
close LOG_FILENAME;
exit 0;
sub delete_all_files_under_path {
(my $file_path) = @_;
print LOG_FILENAME "delete all files and directories under path $file_path\n";
opendir(DIR, $file_path) or die "Couldn't open $file_path. Reasion : $!\n";
while (1) {
my @all_files = readdir(DIR);
my $length = @all_files;
# print "file number is : $length under $file_path\n";
if ( $length == 0 ) {
last;
}
foreach my $file(@all_files) {
# print "current file is : $file\n";
if ( ($file eq ".") || ($file eq "..") ) {
next;
}
my $tmp = File::Spec->catfile($file_path,$file);
# print "deal with current file $tmp\n";
if ( -d $tmp ) {
# print "--delete directory $tmp begin\n";
&delete_directory($tmp);
# print "--delete directory $tmp finished\n";
redo;
} elsif ( -f $tmp) {
unlink "$tmp";
# print "--delet file $tmp finished\n";
}
}
}
}
sub delete_directories_under_path {
(my $file_path) = @_;
print LOG_FILENAME "delete all directories under path $file_path\n";
opendir(DIR, $file_path) or die "Couldn't open $file_path. Reasion : $!\n";
while (1) {
my @all_files = readdir(DIR);
my $length = @all_files;
# print "file number is : $length under $file_path\n";
if ( $length == 0 ) {
last;
}
foreach my $file(@all_files) {
# print "current file is : $file\n";
if ( ($file eq ".") || ($file eq "..") ) {
next;
}
my $tmp = File::Spec->catfile($file_path,$file);
# print "deal with current file $tmp\n";
if ( -d $tmp ) {
# print "--delete directory $tmp begin\n";
&delete_directory($tmp);
# print "--delete directory $tmp finished\n";
redo;
}
}
}
}
sub delete_directory {
(my $file_path) = @_;
# print "again delete all file under $file_path\n";
opendir(DIR, $file_path) or die "Couldn't open $file_path. Reasion : $!\n";
while (1) {
my @all_files = readdir(DIR);
my $length = @all_files;
# print "file number is : $length under $file_path\n";
if ($length eq 0 ) {
rmdir $file_path;
last;
}
foreach my $file (@all_files) {
# print "again current file is : $file\n";
if ( ($file eq ".") || ($file eq "..") ) {
next;
}
my $tmp = File::Spec->catfile($file_path,$file);
# print "again deal with current file $tmp\n";
if ( -d $tmp ) {
&delete_directory($tmp);
# print "again --delete directory $tmp finished\n";
redo;
} elsif ( -f $tmp) {
unlink "$tmp";
# print "again --delete file $tmp over\n";
}
}
}
closedir(DIR);
}
对于上述脚本中的不足之处,请大家交流,多多指正,谢谢。