Nams has asked for the wisdom of the Perl Monks concerning the following question:

Hi all..I am new to perl

Reference:

I want to write a program in perl that should check the environment variables in such a way that they match with some desired variable values(Which is stored in some file text file or xml). These variables could be either a directory,value or path. if the variables are not the same as required..i would like to store it in some log(as in Error,warning or info) and if possible change it to desired value defined in text file. file.

My thought:

To start i decided to use hash to store the existing env variables (i tried using array ..but had few referencing problems).firstly instead of reading the desired value from files i hardcoded them in my program(I will change that later). to make it simpler i added to every line weather it is directory,value or path.

Problem:

Now i want to read the third element of every line and check if its dir,value or path and then compare it with corresponding actual env variable.if it matches then i would say.this is directory and push it into an array of directory, and also to info log.If it doesn't matches then may be error or waring and corrosponding log.

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my %Env = ('PPA_CURRENT_PROJECT' => 'D:\Projects\CurrentProject' => 'D +irectory', 'PPA_DMS' => 'D:\DMS' => 'Directory', 'PPA_DMS_MKL' => 'D:\MKL\ia32\bin' => 'Directory', 'PPA_DataQualityDistributor_CSVFILEPATH' => '\\e4n-00\SR5_ASRRE\CSV' = +> 'Path', 'PPA_DataQualityDistributor_DVLOGSPATH' => '\\e33n-003\SR5_ASRD\DVLOGS +' => 'Path', 'PPA_DataQualityDistributor_INTERMEDIATEFILEPATH' => '\\e34n-001\SR5_A +SRD\INTERMEDIATE' => 'Path', 'USERDNSDOMAIN' => 'PP008.COGY.NET' => 'Value', 'USERDOMAIN' => 'PP008' => 'Value', 'USERNAME' => 'k004lv7w' => 'Value'); #::my @Env_Dir = (\@Env1, \@Env2, \@Env3, \@Env4, \@Env5, \@Env6, \@E +nv7, \@Env8, \@Env9); #::print Dumper \@Env_Dir; my @directory = ();#Array containing environment directory my @path = (); #Array containing environment path my @value = (); #Array containing environment value foreach $_(values %Env) { if ($_ == "Directory") { print 'This is a Directory'; push (@directory, ($Env{$_})); } elsif ($_ == 'Value') { print 'This is a Path'; push (@path, $Env{$_}); } elsif ($_ =='Path') { print 'This is a Value'; push (@value, $Env{$_}); } } print Dumper \@directory; print Dumper \@path; print Dumper \@value;
Please help..any suggestion would help.. Thanks in advance..! Namrata

Replies are listed 'Best First'.
Re: Environment Variable
by almut (Canon) on Apr 13, 2010 at 11:07 UTC
    my %Env = ('PPA_CURRENT_PROJECT' => 'D:\Projects\CurrentProject' => 'Directory', ...

    Hashes store and are initialized from key-value pairs, not triples.  I.e., you probably rather want a data structure like this:

    my %Env = ('PPA_CURRENT_PROJECT' => [ 'D:\Projects\CurrentProject' => +'Directory' ], ...

    or

    my %Env = ('PPA_CURRENT_PROJECT' => { value => 'D:\Projects\CurrentProject', type => 'Directory' }, ...

    With the latter, you could, for example, access the type using

    $Env{PPA_CURRENT_PROJECT}{type}
Re: Environment Variable
by moritz (Cardinal) on Apr 13, 2010 at 11:03 UTC
    You've already loaded Data::Dumper, so the next step is to actually use it:
    print Dumper \%Env;

    This will show you one thing: %Env doesn't have the structure you wish it to have. The simplest way around is to use two hashes: one for storing the key => value mapping, and one for key => type (ie file or directory).

    Another possible solution is to store more complicated data structures - see perlreftut and perldsc for some introductions on how to deal with them.

Re: Environment Variable
by choroba (Cardinal) on Apr 13, 2010 at 11:07 UTC
    There are several problems in your code:
    1. The hash you declare is probably not what you wanted to be. Use Dumper to have a look at it, or just try print %Env{Path} - you perhaps meant something like
      my %Env = ('PPA_CURRENT_PROJECT' => ['D:\Projects\CurrentProject' => ' +Directory' ], ...
    2. To compare string values, do not use == (it is used for numbers). The right operator is eq.
Re: Environment Variable
by apl (Monsignor) on Apr 13, 2010 at 11:14 UTC
    Side comment... You may want to run perltidy on your code. Your script may be simple now, but it is already harder than necessary to follow because of the lack of indentation.
      Thank you monks for finding time to answer me..
      I am following the solution provided by 'BioLion' monk...and changed the hash definition accordingly..
      Thanks a lot It really helped..
      Namrata
Re: Environment Variable
by BioLion (Curate) on Apr 13, 2010 at 11:12 UTC

    It sounds like you want to compare two hashes, warning on any differences and updating so that values match the second hash? If I am right you might try something like this (pseudocode!):

    ## Hash 1 : %ENV ## Hash 2 : Desired my %desired = ( A => 1, B => 2 ...); ## loop through Hash 2, checking against Hash 1 for my $key ( keys %desired){ if (exists ($ENV{$key})){ warn ">$key< exists in both hashes\n"; if ( $desired{$key} eq $ENV{$key} ){ ## simple text compare warn ">$key< has the same value in both hashes\n"; } else { warn ">$key< has different values:\t ENV : $ENV{$key}\n\tD +ESIRED : $desired{$key}\n"; ## updating $ENV{$key} = $desired{$key}; } } else { warn ">$key< Only exists in DESIRED\n"; } }

    Also - multi dimensional hashes are coded as %hash = (key1 => {key2 => value},); or $hash->{key1}->{key2} = 'value'; see perlref. HTH.

    Just a something something...