LX-PERL-INFO-globbing-stat
Updated aug/03/2010 01:54

globbing en stat

  1. globbing

    Bestandsnamen oproepen aan de hand van wildcards noemen we globbing. Dat doen we in perl als volgt:

    @files = <*>;

    In @files zitten nu alle files uit de huidige directory. Met een foreach kunnen we die nu één na één behandelen.

    Zo kan het ook:

    $path='/etc';

    $conffiles='.conf';
    @files=(<$path/*$conffiles>);

    En daar zouden we dan het volgende mee kunnen bouwen:

    #!/usr/bin/perl
    #
    # etcconfglobber: globbing voor conf files in etc
    #
    $path='/etc';
    $conffiles='.conf';
    @files=(<$path/[a-e]*$conffiles>); # alle files in /etc/[a-e]*.conf
    foreach $x (@files)
    {
    print "$x\n";
    }

    Met als output:

    $ etcconfglobber.pl
    /etc/adduser.conf
    /etc/blkid.conf
    /etc/ca-certificates.conf
    /etc/cvs-cron.conf
    /etc/cvs-pserver.conf
    /etc/debconf.conf
    /etc/deluser.conf


    Je moet wel oppassen met wildcards die je in een variabele stopt: daarvoor heb je de glob operator nodig.

  2. stat

    Met de operator stat halen we informatie van een bestand op:

    ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $bsize, $blocks) = stat($filename);

    @filestat = stat($filename)
    $extracted_element = $filestat[index];

    $extracted_element = (stat($filename))[index];

    $dev   = (stat($filename))[0]     # device
    $ino   = (stat($filename))[1]     # inode    
    $mode  = (stat($filename))[2]     # file type and permission
    $nlink = (stat($filename))[3]     #
    number of hard links
    $uid   = (stat($filename))[4]     # user id

    $gid   = (stat($filename))[5]     # group id
    $rdev  = (stat($filename))[6]     # the dev id (special files only)
    $size  = (stat($filename))[7]     # size
    $atime = (stat($filename))[8]     # access time
    $mtime = (stat($filename))[9]     # modification time
    $ctime = (stat($filename))[10]    # creation time
    $bsize = (stat($filename))[11]    # blocksize
    $blocks= (stat($filename))[12]    # amount of blocks 

    Hiermee bouwen we volgend rudimentair script:

    #!/usr/bin/perl
    #
    # ls.pl: globbing
    #
    @opzoeking=@ARGV;

    foreach $x (@opzoeking)
    {
            @alles=stat($x);
            print "$x: ";
            for ($i=0; $i<=12; $i++)
            {
                    print "$alles[$i] ";
            }
            print "\n";
    }

    Met als output:

    $ ls.pl /etc/* | column -t | head
    /etc/acpi:         2070  899368  16877  3  0 0 0  4096 1272364137  1272364137  1274646798  4096  8
    /etc/adduser.conf: 2070  899500  33188  1  0 0 0  2981 1276452447  1272362612  1274646664  4096  8
    /etc/akonadi:      2070  901687  16877  2  0 0 0  4096 1274649680  1274649704  1274649704  4096  8
    /etc/alternatives: 2070  899369  16877  2  0 0 0 12288 1274011697  1280483393  1280483393  4096 24
    /etc/anacrontab:   2070  899501  33188  1  0 0 0   395 1280651136  1267756283  1274646664  4096  8
    /etc/apache2:      2070  901879  16877  7  0 0 0  4096 1280171903  1274814586  1274814586  4096  8
    /etc/apm:          2070  899370  16877  6  0 0 0  4096 1272363233  1272363233  1274646798  4096  8
    /etc/apparmor:     2070  899371  16877  3  0 0 0  4096 1272822104  1272822104  1274646798  4096  8
    /etc/apparmor.d:   2070  899372  16877  5  0 0 0  4096 1272822105  1278538650  1278538650  4096  8
    /etc/apport:       2070  901632  16877  4  0 0 0  4096 1274689599  1274689603  1274689603  4096  8


    We kunnen de output wat aanpassen als volgt:

    $ cat ls-l.pl
    #!/usr/bin/perl
    #
    # ls-l.pl: een ls -l zonder bash
    #
    @opzoeking=@ARGV;

    foreach $x (@opzoeking)
    {
        @alles=stat($x);
        print "$x: ";
        for ($i=0; $i<=12; $i++)
         {
            if ($i==2)        {
                $drukaf=$alles[$i];
                $drukaf=sprintf("%o", $drukaf);
                print "perm:".$drukaf." ";        }
            elsif ($i==4)        {
                $drukaf=$alles[$i];
                print "uid:".$drukaf." ";        }
            elsif ($i==5)        {
                $drukaf=$alles[$i];
                print "gid:".$drukaf." ";        }
            elsif ($i==7)        {
                $drukaf=$alles[$i];
                print "size:".$drukaf." ";        }
            elsif ($i==9)        {
                $drukaf=localtime($alles[$i]);
                print "time:".$drukaf." ";        }
        }
        print "\n";
    }

    De functie localtime formatteert de datum, met sprintf formaat "%o" zetten we de permissions om van decimaal naar octaal:

    $ ls-l.pl /etc/* | head | column -t
    /etc/acpi:          perm:40755   uid:0  gid:0  size:4096   time:Tue  Apr  27  12:28:57  2010
    /etc/adduser.conf:  perm:100644  uid:0  gid:0  size:2981   time:Tue  Apr  27  12:03:32  2010
    /etc/akonadi:       perm:40755   uid:0  gid:0  size:4096   time:Sun  May  23  23:21:44  2010
    /etc/alternatives:  perm:40755   uid:0  gid:0  size:12288  time:Fri  Jul  30  11:49:53  2010
    /etc/anacrontab:    perm:100644  uid:0  gid:0  size:395    time:Fri  Mar  5   03:31:23  2010
    /etc/apache2:       perm:40755   uid:0  gid:0  size:4096   time:Tue  May  25  21:09:46  2010
    /etc/apm:           perm:40755   uid:0  gid:0  size:4096   time:Tue  Apr  27  12:13:53  2010
    /etc/apparmor:      perm:40755   uid:0  gid:0  size:4096   time:Sun  May  2   19:41:44  2010
    /etc/apparmor.d:    perm:40755   uid:0  gid:0  size:4096   time:Wed  Jul  7   23:37:30  2010
    /etc/apport:        perm:40755   uid:0  gid:0  size:4096   time:Mon  May  24  10:26:43  2010

    en dat kunnen we vergelijken met:


    $ ls -ld /etc/* | head
    drwxr-xr-x 3 root    root      4096 2010-04-27 12:28 /etc/acpi
    -rw-r--r-- 1 root    root      2981 2010-04-27 12:03 /etc/adduser.conf
    drwxr-xr-x 2 root    root      4096 2010-05-23 23:21 /etc/akonadi
    drwxr-xr-x 2 root    root     12288 2010-07-30 11:49 /etc/alternatives
    -rw-r--r-- 1 root    root       395 2010-03-05 03:31 /etc/anacrontab
    drwxr-xr-x 7 root    root      4096 2010-05-25 21:09 /etc/apache2
    drwxr-xr-x 6 root    root      4096 2010-04-27 12:13 /etc/apm
    drwxr-xr-x 3 root    root      4096 2010-05-02 19:41 /etc/apparmor
    drwxr-xr-x 5 root    root      4096 2010-07-07 23:37 /etc/apparmor.d
    drwxr-xr-x 4 root    root      4096 2010-05-24 10:26 /etc/apport


    We gebruiken nu nog functies die een uid omzetten naar een login (getpwuid), gid naar groupnaam (getgrgid), en tenslotte nog een functie om de permissions conventioneel af te drukken. Dat laatste kan je met de module Stat::lsMode - je kan zelf uitzoeken hoe dat moet.

    #!/usr/bin/perl
    #
    # ls.pl: globbing
    #
    @opzoeking=@ARGV;

    foreach $x (@opzoeking)
    {
        @alles=stat($x);
        for ($i=0; $i<=12; $i++)
         {
            if    ($i==2)        {
                $perms=sprintf("%o",$alles[$i]);
                print $perms." ";    }
            elsif ($i==4)        {
                $login = (getpwuid($alles[$i]))[0];
                print $login." ";        }
            elsif ($i==5)        {
                $group = (getgrgid($alles[$i]))[0];
                print $group." ";        }
            elsif ($i==7)        {
                $grootte=$alles[$i];
                print $grootte." ";        }
            elsif ($i==9)        {
                $modiftime=localtime($alles[$i]);
                print $modiftime." ";        }
        }
        print "$x \n";
    }

    output:

    $ ls-l.pl /etc/* | head | column -t
    40755   root  root  4096   Tue  Apr  27  12:28:57  2010  /etc/acpi
    100644  root  root  2981   Tue  Apr  27  12:03:32  2010  /etc/adduser.conf
    40755   root  root  4096   Sun  May  23  23:21:44  2010  /etc/akonadi
    40755   root  root  12288  Fri  Jul  30  11:49:53  2010  /etc/alternatives
    100644  root  root  395    Fri  Mar  5   03:31:23  2010  /etc/anacrontab
    40755   root  root  4096   Tue  May  25  21:09:46  2010  /etc/apache2
    40755   root  root  4096   Tue  Apr  27  12:13:53  2010  /etc/apm
    40755   root  root  4096   Sun  May  2   19:41:44  2010  /etc/apparmor
    40755   root  root  4096   Wed  Jul  7   23:37:30  2010  /etc/apparmor.d
    40755   root  root  4096   Mon  May  24  10:26:43  2010  /etc/apport