Chinaunix

标题: 我想用perl实现 遍历一个工作目录下所有的exe和bat文件 并且执行 请问如果编写 [打印本页]

作者: zca7    时间: 2007-01-17 12:06
标题: 我想用perl实现 遍历一个工作目录下所有的exe和bat文件 并且执行 请问如果编写
我想用perl实现 遍历一个工作目录下所有的exe和bat文件 并且执行 请问如果编写 最好还能按周期来计划执行 请教一下

里是不是用exec更合适?
作者: gig2600    时间: 2007-01-17 12:31
vbscript实现起来更容易写,也不用装activeperl
作者: alexru    时间: 2007-01-17 14:44
File::Find
作者: flw    时间: 2007-01-17 15:08
原帖由 alexru 于 2007-1-17 14:44 发表
File::Find

不带子目录的话,
(<*.exe> <*.bat>)
作者: zca7    时间: 2007-01-17 16:26
咱们这回帖还很快的啊 不好意思我是个新手 刚刚接触这个 底子薄
#! c:\perl\bin\perl -w

use File::Find;


find( \&handleFind, 'D:/1');

sub handleFind{
       
        system (<*.bat>);
       
        }


exit;

这个是我写的 我再1目录下放了两个bat 可是它只是把第一个bat执行了3遍~第二个的都没动 为什么啊?
作者: zca7    时间: 2007-01-17 16:29
这个不是会递归搜索嘛~
还有如果我把system换成exec的话 就只是执行一遍
作者: apile    时间: 2007-01-17 16:41
debug的第一步..请先打印出来看看...
你到底 find到的什麽内容..
作者: zca7    时间: 2007-01-17 16:49
我再“sub handleFind{ ”下一行加了print  "$File::find:name\n";
可以输出这个目录下的两个bat
D:\>bat.pl
D:/1
D:/1/a.bat
D:/1/b.bat
作者: Namelessxp    时间: 2007-01-17 17:03
大才小用了,2k以上的,用批处理就可以解决
作者: apile    时间: 2007-01-17 17:09
那难怪会执行三次啦..
<*.bat>会回传a.bat b.bat的array...
system(<*.bat>) ;
等於
system("a.bat b.bat");
你觉得他会执行a.bat,b.bat吗?

请再多想想...你已经解决了一半的问题.....
作者: zca7    时间: 2007-01-17 17:18
原帖由 Namelessxp 于 2007-1-17 17:03 发表
大才小用了,2k以上的,用批处理就可以解决

批处理只能call单个bat 不能同时call多个吧

我再努力努力~
作者: Namelessxp    时间: 2007-01-17 17:33
原帖由 zca7 于 2007-1-17 17:18 发表

批处理只能call单个bat 不能同时call多个吧

我再努力努力~


  1. @ECHO OFF
  2. @FOR /F "usebackq eol=. tokens=1,3* delims= " %%i IN (`DIR *.BAT /T:C`)  DO IF EXIST %%k IF NOT "%0" == "%%k" IF NOT "%0.bat" == "%%k" IF NOT "%0.cmd" == "%%k" @START /B %%k
  3. @FOR /F "usebackq eol=. tokens=1,3* delims= " %%i IN (`DIR *.EXE /T:C`)  DO IF EXIST %%k IF NOT "%0" == "%%k" IF NOT "%0.bat" == "%%k" IF NOT "%0.cmd" == "%%k" @START /B %%k
复制代码

作者: zca7    时间: 2007-01-17 17:41
深了 我慢慢看看 学学
作者: Ecore    时间: 2007-01-17 18:40
应该用opendir,readdir先读到目录中所有的文件吧。然后用glob,取.exe .bat文件,
并用system调用执行。。当然是放到循环内。

exec和system调用方式不一样。exec用新进程覆盖当前进程。system则用fork创建一个,然后再调用exec
作者: zca7    时间: 2007-01-17 18:41
那如果包含子目录呢?
作者: Namelessxp    时间: 2007-01-17 18:43
原帖由 zca7 于 2007-1-17 18:41 发表
那如果包含子目录呢?


递归最方便,批处理就不好处理了
作者: zca7    时间: 2007-01-17 19:11
#! c:\perl\bin\perl -w

my $mydir = "d:/1";
opendir (DIR,$mydir);        
readdir (DIR);              
while(<DIR>)              
{                             
        if ($_=~(\s+).(bat));
        {
        $batcname=$2;                 
        system($batcname);
       
        };
           
}              

exit   ;   


是这样嘛 第八句报错 我不太知道
作者: zca7    时间: 2007-01-17 19:19
不好意思啊 实在不会 能不能提供一个完整得 我读读啊
作者: zca7    时间: 2007-01-17 19:40
我google了一下 Modules: File::Find  然后改了一下 ok了 解决了
贴出来 瞧瞧  (有两句我还没都看懂 hehe~)

#! c:\perl\bin\perl -w

use strict;
use File::Find;

my %directories;
find( \&filehandler, "d:/1" );

for my $filename ( sort keys %directories ) {
    my @dirlist = @{$directories{ $filename } };
    if ( scalar @dirlist => 1 ) {
       # print "$filename\n";
        for ( @dirlist ) {
       #    print  "$_".'/'."$filename\n";
           my $bat = "$_".'/'."$filename\n";
           system ("$bat");
            }
        }   # if
    }   # for

sub filehandler {
    # Check to make sure that it's a file, not a directory
    return unless -f $File::Find::name;

    # Just take the filename, and convert to lowercase
    my $nameonly = lc $_;

    # See if it's a .bat file
    return unless $nameonly =~ m/\.(bat)$/i;

    $directories{ $nameonly } = [] unless defined $directories{ $nameonly };
    push( @{$directories{ $nameonly } }, $File::Find::dir );


不过还有个很关键得问题 我想要这些遍历出来得bat文件一起执行 或者是隔一会顺序执行
但是要按照上面得代码得话 就会等第一个完全执行完了才会执行第二个 请问怎么解决?

[ 本帖最后由 zca7 于 2007-1-17 20:05 编辑 ]
作者: 路小佳    时间: 2007-01-17 19:46
system ("cmd.exe /c $bat");
作者: zca7    时间: 2007-01-17 19:55
标题: 回复 20楼 路小佳 的帖子
好像不太好使~
作者: ulmer    时间: 2007-01-18 17:27
标题: 回复 1楼 zca7 的帖子
Hello,

to start more than 2 programms (or multi process) in parallel under MS WINDOWS, one of the methods is to use Win32::Process module from CPAN.
For example, you can try this under commander line:
c:> notepad.exe & mspaint.exe
it will start those 2 application at same time.

How to use perl to deal with? here is a simple demo:
use strict;
use warnings;

use Win32::Process;

my $dir = 'C:\\WINNT';
opendir DH, $dir or die $!;
my $ps = 0;
while (my $file = readdir DH) {
    # demo for excuting 2 application in parallel
    if ($file eq 'notepad.exe' or $file eq 'regedit.exe') {
        Win32::Process::Create(
            $ps,
            "$dir\\$file",
            '',
            0,
            CREATE_NEW_CONSOLE,
            '.'
        );
    }
    $ps++;
}
closedir DH;


for more info, pls use perldoc Win32::Process.

--ulmer

[ 本帖最后由 ulmer 于 2007-1-18 17:28 编辑 ]
作者: roywangt    时间: 2007-01-19 09:32
#!/usr/bin/perl
use File::Find;
sub process_file {
    system $File::Find::name  if (m/exe$|bat$/);
       
}
print "Hello, World...\n";
$mainPath="E:\\CODE";
print $mainPath."\n";

find(\&process_file, $mainPath);

在定时处理方面,可以用windows的任务管理,或者unix corntab 实现

[ 本帖最后由 roywangt 于 2007-1-19 09:33 编辑 ]
作者: zca7    时间: 2007-01-19 13:13
thanks for everybody,i will try it.




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2