Toon posts:

[Perl] Wijzigingsdatum bestand veranderen

Pagina: 1
Acties:

Verwijderd

Topicstarter
Als beginnend Perl-programmeur ben ik bezig om een programmaatje te schrijven dat een directorystructuur recursief doorzoekt naar bestanden die 'test.dat' heten. Als zo'n bestand gevonden wordt, moet de datum van laatste wijziging van dat bestand veranderd worden in de huidige datum min één week (dus op vorige week... :))

Ik heb tot nu toe de volgende code, die eerlijk gezegd een bij elkaar geraapt zooitje code is van diverse Perl sites:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/perl

use File::Find;
use File::Spec;

pgrep(path => 'Data', filename => qr/test\.dat/, content  => qr/./);

my %defaults = (path => '.', filename => qr/./, content => qr/./);

sub pgrep {
    my %params = (%defaults, @_);
    my @matches;
    my ($dir,$dcount) = File::Spec->rel2abs($params{path});
    
    $dcount = @$dcount = $dir =~ /\\\.\./g;
    $dir =~ s/(\\.*?){$dcount}(\\\.\.){$dcount}//;
    
    my $count = 0;
    find(sub{$File::Find::name =~ s/\//\\/g;
        if (-f and /$params{filename}/) {
            local $/;
            push @matches, $File::Find::name;
            $newtime = time() - 604800;
            utime ($newtime, $newtime, $File::Find::name);
        }
         },
        $dir);

     print "$_\n"  foreach (sort {lc($a) cmp lc($b)} @matches);
}

Onder Windows werkt dit prima. Ik zie in de Explorer de datum van de test.dat-bestanden keurig veranderen. De bedoeling is echter dat dit programma op een Apache server komt te draaien en daar verandert er helemaal niets! Weet iemand hoe dit komt?
Heeft dit misschien met bepaalde rechten te maken? Alle test.dat bestanden heb ik de permissies 766 gegeven, maar dit helpt niets...

  • tomato
  • Registratie: November 1999
  • Niet online
Hmmm wat overkill dit scriptje, maar goed ;)

Gebeurt er helemaal niets? Bevat @matches wel ieder bestand dat je aangepast had willen zien?

  • tomato
  • Registratie: November 1999
  • Niet online
Hebben je je directories ook 766 gegeven?

Verwijderd

Topicstarter
Het is inderdaad nogal een rotzooiscript maar goed... :)

@matches bevat inderdaad de bestanden die veranderd moeten worden, dus dan zullen die permissies van die directories waarschijnlijk ook wel goed staan, of niet?

Oftewel: het recursief doorzoeken van de directories en het indentificeren van de bestanden gaat goed, de rest niet.

  • tomato
  • Registratie: November 1999
  • Niet online
Verander
code:
1
utime ($newtime, $newtime, $File::Find::name);

eens in
code:
1
utime $newtime, $newtime, $File::Find::name or print "Niet aangepast\n";

utime() geeft namelijk het aantal bestanden dat aangepast is als return value. Wanneer dit 0 is (false) wordt het statement achter de 'or' uitgevoerd.

Verwijderd

Topicstarter
Ok, alvast bedankt!

Ik kan het nu helaas niet testen, omdat ik nu niet achter de goede computer zit (morgenvroeg pas...)

Maar is het ook mogelijk om een soort error description van de utime functie te tonen, zodat je kunt zien waarom ie faalt?

Verwijderd

Topicstarter
Ok, ik ben erachter gekomen waarom de utime functie niet werkt: de variabele $File::Find::name bevat het '\'-teken als scheidingsteken tussen de directories. Als ik de utime functie direct aanroep met het '/'-teken als scheidingsteken tussen de directories, werkt het wel!

Heeft iemand hier een verklaring voor? Moet ik nou via een of andere functie alle '\' in '/' veranderen? :?

Verwijderd

Topicstarter
Dit is de uiteindelijke, werkende, code geworden:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/perl

use File::Find;
use File::Spec;

pgrep(path => 'Data', filename => qr/test\.dat/, content  => qr/./);

my %defaults = (path => '.', filename => qr/./, content => qr/./);

sub pgrep {
    my %params = (%defaults, @_);
    my ($dir,$dcount) = File::Spec->rel2abs($params{path});

    print "Bezig met zoeken...\n\n";

    find(
        sub {
            if (-f and /$params{filename}/) {
                local $/;
                $newtime = time() - 1000000;
                $result = utime $newtime, $newtime, $File::Find::name;

                if ($result == 0) {
                    print "Fout bij aanpassen datum: $File::Find::name\n"
                }
                else {
                    print "OK: $File::Find::name\n"
                }
            }
        },
    $dir
    );
    print "\nKlaar met zoeken.\n";
}

Zit ik alleen nog met één klein probleempje: welke waarde moet ik kiezen om de datum precies één week terug te zetten. Als ik 7 * 24 * 60 * 60 = 604800 kies klopt het niet...

Verwijderd

Topicstarter
Sorry, maar ik ga jullie nog eenmaal lastigvallen :)

Hoe kan ik ervoor zorgen dat de utime functie ook via het internet gebruikt kan worden? Het bovenstaande programma werkt nou namelijk prima wanneer het via een telnetsessie op de server gestart wordt, maar niet wanneer het via een browser aangeroepen wordt...

Heeft dit ermee te maken dat een internetgebruiker maar beperkte rechten en zo ja, hoe kan ik dit (in de code?) veranderen?

Alvast hartelijk dank!
Pagina: 1