Script PERL para comparar el uso de la partición de hoy con el de ayer en diferentes hosts usando un archivo CSV

3 minutos de lectura

Soy nuevo en perl y tengo problemas para construir mi primer script, pero el módulo de partición no funciona. Más detalles se comentan en el código. Tal vez el código debería reescribirse usando hash y referencia, pero no tengo idea de cómo hacerlo. ¿Puede alguien por favor ayudarme?

#!/usr/bin/perl -w

#This script compares the today's result and yesterday's results between partitions for each host.
#The "df" output is stored in a CSV file. If any partitions have been changed (mounted/unmounted)
#the script must to warn and don't compare the results for that host.

use warnings;

my $file = "/tmp/df.csv";
my $host = `hostname | awk -F'.' '{print \$1}'`;
my $yesterdays_date = `date -d "-1 day" '+%d.%m.%Y'`;
my $todays_date = `date '+%d.%m.%Y'`;
chomp ($host, $yesterdays_date, $todays_date);

open(HANDLE, "$file") or die "Error opening file $file: $!";
my @array = <HANDLE>;

foreach (@array){
     @columns = split /,/;

        if(/$host/ and /$todays_date/){
            my $todays_result = $columns[5];chomp;
            #my $todays_partition = $columns[6];chomp;

            print "Today\'s disk usage on $host: $columns[5]\n";
            #print "$todays_result <<T.Result      T.Partition>> $todays_partition"
        }

        elsif(/$host/ and /$yesterdays_date/){
            my $yesterdays_result = $columns[5];chomp;
            #my $yesterdays_partition = $columns[6];chomp;
 print "Yesterday\'s disk usage on $host: $columns[5]\n";
            #print "$yesterdays_result <<Y.Result     Y.Partition>>  $yesterdays_partition";
        }

        #Debug: Print differences in mount point (condition must be "ne" instead eq)
        #if ($todays_partition eq $yesterdays_partition){
        #print "$todays_partition <<Partition equal>> $yesterdays_partition";
        #}

        #else{
            #print "Debug: Host or Date DIFFERENT or NOT FOUND for today and yesterday\n";
        #}

        #TO DO: print "The diference: $todays_result-$yesterdays_result", "\n";
};

close HANDLE;

El archivo CSV contiene las siguientes líneas:

testhost,25.08.2018,100M,0,100M,0,/run/user/0
localhost,01.09.2018,6.7G,1.5G,5.2G,23,/
localhost,01.09.2018,485M,0,485M,0,/dev
localhost,01.09.2018,496M,4.0K,496M,1,/dev/shm
localhost,01.09.2018,496M,6.7M,490M,2,/run
localhost,01.09.2018,496M,0,496M,0,/sys/fs/cgroup
localhost,01.09.2018,497M,110M,387M,23,/boot
localhost,01.09.2018,100M,0,100M,0,/run/user/0
localhost,02.09.2018,6.7G,1.5G,5.2G,23,/
localhost,02.09.2018,485M,0,485M,0,/dev
localhost,02.09.2018,496M,4.0K,496M,1,/dev/shm
localhost,02.09.2018,496M,6.7M,490M,2,/run
localhost,02.09.2018,496M,0,496M,0,/sys/fs/cgroup
localhost,02.09.2018,497M,110M,387M,23,/boot
localhost,02.09.2018,100M,0,100M,0,/run/user/0

Bono: Ayuda con la gramática inglesa 😀

  • Qué “módulo de partición“¿Tienes en mente?

    – zdim

    3 de septiembre de 2018 a las 0:56

  • Se supone que el módulo de partición verifica cada línea de partición montada desde ayer hasta hoy y en el futuro usa este resultado para calcular cuánto ha crecido la partición en un día.

    – jtech

    3 de septiembre de 2018 a las 8:34

  • OK, entonces es lo que estás escribiendo. Pensé que podría haberse referido a algún módulo CPAN o algo así.

    – zdim

    3 sep 2018 a las 18:31

avatar de usuario
ikegami

Necesita información de varias líneas, por lo que necesitará algunas variables fuera del bucle.

Si los registros en el CSV están ordenados cronológicamente, puede usar lo siguiente:

use strict;
use warnings;

use DateTime      qw( );
use Sys::Hostname qw( hostname );
use Text::CSV_XS  qw( );

my $qfn = "/tmp/df.csv";
open(my $fh, '<', $qfn)
   or die("Can't open \"$qfn\": $!\n");

my $target_host = hostname =~ s/\..*//rs;   # /

my $today_dt = DateTime->now( time_zone => "local" )->set_time_zone("floating")->truncate( to => "day" );
my $yday_dt  = $today_dt->clone->subtract( days => 1 );

my $today = $today_dt->strftime("%d.%m.%Y");
my $yday  = $yday_dt ->strftime("%d.%m.%Y");

my $csv = Text::CSV_XS->new({ auto_diag => 2, binary => 1 });

my %yday_usage_by_partition;   
while ( my $row = $csv->getline($fh) ) {
   my ($host, $date, $partition, $usage) = @$row[0,1,6,5];
   next if $host ne $target_host;

   if ($date eq $yday) {
      $yday_usage_by_partition{$partition} = $usage;
   }
   elsif ($date eq $today) {
      if (!exists($yday_usage_by_partition{$partition})) {
         warn("No data for $yday for partition $partition\n");
         next;
      }

      print("$partition: $$yday_usage_by_partition{$partition} -> $usage\n");
   }
}

¿Ha sido útil esta solución?