Linux Perl检查子目录并更改onwership

Linux Perl检查子目录并更改onwership,linux,perl,subroutine,chown,Linux,Perl,Subroutine,Chown,我试图编写一个perl脚本,它检查当前目录中的所有目录,然后相应地渗透到后续目录中,直到包含最后一个目录。这是我写的: #!/usr/bin/perl -w use strict; my @files = <*>; foreach my $file (@files){ if (-d $file){ my $cmd = qx |chown deep:deep $file|; my $chdir = qx |cd $file|;

我试图编写一个perl脚本,它检查当前目录中的所有目录,然后相应地渗透到后续目录中,直到包含最后一个目录。这是我写的:

#!/usr/bin/perl -w
use strict;
my @files = <*>;
foreach my $file (@files){
    if (-d $file){
            my $cmd = qx |chown deep:deep $file|;
            my $chdir = qx |cd $file|;
            my @subfiles = <*>:
            foreach my $ subfile(@subfiles){
                if (-d $file){
                    my $cmd = qx |chown deep:deep $subfile|;
                    my $chdir = qx |cd $subfile|;
            .  # So, on in subdirectories
            .
            .
            }
    }

    }
 }
#/usr/bin/perl-w
严格使用;
我的@files=;
foreach my$文件(@files){
如果(-d$file){
my$cmd=qx | chown deep:deep$file |;
我的$chdir=qx | cd$文件|;
我的@subfiles=:
foreach my$子文件(@subfiles){
如果(-d$file){
my$cmd=qx | chown deep:deep$subfile |;
我的$chdir=qx | cd$子文件|;
.#因此,在子目录中继续
.
.
}
}
}
}
现在,一些目录我有大约50个子目录。如果不写50个if条件,我如何才能穿透它?请建议。谢谢。

好吧,CS101方法(如果这只是一个练习)是使用递归函数

sub dir_perms {
 $path = shift;
  opendir(DIR, $path);
  my @files = grep { !/^\.{1,2}$/ } readdir(DIR); # ignore ./. and ./..
  closedir(DIR);
  for (@files) {
   if ( -d $_ ) {
    dir_perms($_);
  }
  else {
   my $cmd = qx |chown deep:deep $_|;
   system($cmd);
  }
 }
}

dir_perms(".");
但我也会看看File::Find,寻找更优雅、更健壮的东西(这可能会陷入循环链接陷阱,如果你不在目录上调用它,就会出错,等等),为此,我会看看普通的旧UNIX Find(1),它可以做你正试图用-exec选项做的事情,例如

/bin/bash$ find /path/to/wherever -type f -exec chown deep:deep {} \;
CS101的一种方法(如果这只是一个练习)是使用递归函数

sub dir_perms {
 $path = shift;
  opendir(DIR, $path);
  my @files = grep { !/^\.{1,2}$/ } readdir(DIR); # ignore ./. and ./..
  closedir(DIR);
  for (@files) {
   if ( -d $_ ) {
    dir_perms($_);
  }
  else {
   my $cmd = qx |chown deep:deep $_|;
   system($cmd);
  }
 }
}

dir_perms(".");
但我也会看看File::Find,寻找更优雅、更健壮的东西(这可能会陷入循环链接陷阱,如果你不在目录上调用它,就会出错,等等),为此,我会看看普通的旧UNIX Find(1),它可以做你正试图用-exec选项做的事情,例如

/bin/bash$ find /path/to/wherever -type f -exec chown deep:deep {} \;

perldoc File::Find提供了您正在做的事情的示例。例如

       use File::Find;
       finddepth(\&wanted, @directories_to_search);
       sub wanted { ... }
在文档的后面,它说您可以使用find2perl创建想要的{}子程序

 find2perl / -name .nfs\* -mtime +7 \
           -exec rm -f {} \; -o -fstype nfs -prune

perldoc File::Find提供了您正在做的事情的示例。例如

       use File::Find;
       finddepth(\&wanted, @directories_to_search);
       sub wanted { ... }
在文档的后面,它说您可以使用find2perl创建想要的{}子程序

 find2perl / -name .nfs\* -mtime +7 \
           -exec rm -f {} \; -o -fstype nfs -prune
注意:除非您是超级用户(即root用户),否则操作系统通常不允许您更改文件或目录的所有权

现在,我们解决了这个问题

File::Find
模块执行您想要的操作。使用
使用警告而不是
-w

use strict;
use warnings;
use feature qw(say);
use autodie;
use File::Find;

finddepth sub {
    return unless -d;    #  You want only directories...
    chown deep, deep, $File::Find::name
        or warn qq(Couldn't change ownership of "$File::Find::name\n");
}, ".";
File::Find
包将
Find
finddepth
子例程导入Perl程序

两者的工作原理几乎相同。它们都递归到您的目录中,并且都将用于对找到的文件进行操作的子例程和要操作的目录列表作为第一个参数

该文件的名称被放置在
$\uu
中,您也被放置在该文件的目录中。这使得在文件上运行标准变得很容易。在这里,我拒绝任何不是目录的东西。这是我将使用
$\uu
作为默认值的少数几个地方之一

文件的全名(来自您正在搜索的目录)位于
$file::Find::name
中,该文件的目录名为
$file::Find::dir

我更喜欢将我的子例程嵌入到我的
find
中,但您也可以将对另一个子例程的引用放在其中。这两者或多或少是等效的:

my @directories;
find sub {
   return unless -d;
   push @directories, $File::Find::name;
}, ".";


my @directories;
find \&wanted, ".";

sub wanted {
   return unless -d;
   push @directories, $File::Find::name;
}
在这两个目录中,我收集路径中所有目录的名称,并将它们放入
@目录中
。我喜欢第一个目录,因为它将我想要的子例程和我的
查找
放在一起。另外,我的子例程中神秘的未声明的
@目录
看起来并不那么神秘和未声明。我决定ared
my@directories;
位于
find
的正上方

顺便说一句,这就是我通常使用的
find
。我会找到我想要的,并将它们放入数组中。否则,你就无法将所有代码放入你想要的子例程中。

注意:除非你是超级用户(即root用户),否则操作系统通常不允许你更改文件或目录的所有权

现在,我们解决了这个问题

文件::查找
模块执行您想要的操作。使用
使用警告;
而不是
-w

use strict;
use warnings;
use feature qw(say);
use autodie;
use File::Find;

finddepth sub {
    return unless -d;    #  You want only directories...
    chown deep, deep, $File::Find::name
        or warn qq(Couldn't change ownership of "$File::Find::name\n");
}, ".";
File::Find
包将
Find
finddepth
子例程导入Perl程序

两者的工作原理基本相同。它们都会深入到您的目录中,并且都将用于对找到的文件进行操作的子例程和要操作的目录列表作为第一个参数

文件名被放置在
$\uuu
中,您被放置在该文件的目录中。这使得在该文件上运行标准变得很容易。在这里,我拒绝任何不是目录的内容。这是我将使用
$\uu
作为默认设置的少数地方之一

文件的全名(来自您正在搜索的目录)位于
$file::Find::name
中,该文件的目录名为
$file::Find::dir

我更喜欢将我的子例程嵌入到我的
find
中,但您也可以将对另一个子例程的引用放在其中。这两者或多或少是等效的:

my @directories;
find sub {
   return unless -d;
   push @directories, $File::Find::name;
}, ".";


my @directories;
find \&wanted, ".";

sub wanted {
   return unless -d;
   push @directories, $File::Find::name;
}
在这两个目录中,我收集路径中所有目录的名称,并将它们放入
@目录中
。我喜欢第一个目录,因为它将我想要的子例程和我的
查找
放在一起。另外,我的子例程中神秘的未声明的
@目录
看起来并不那么神秘和未声明。我决定ared
my@directories;
位于
find
的正上方


顺便说一下,这就是我通常使用的
find
。我会找到我想要的,并将它们放入数组中。否则,您将无法将所有代码放入所需的子例程中。

请您给出一个示例。谢谢。如果出于某种原因