Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

conf file in Perl syntax

by Ravendark (Acolyte)
on Jun 11, 2009 at 08:28 UTC ( [id://770562]=perlquestion: print w/replies, xml ) Need Help??

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

Hello! I am new to Perl (I usually write Java) and I am trying to write some programs in Perl that use Telnet and acquire some info from some machines. What I want to do is: to have a conf file in Perl syntax like:
$config = { host_1 => '192.168.1.1', host_2 => '192.168.1.2', host_3 => '192.168.1.3', host_4 => '192.168.1.4' };
...and read this into my program and store it in an array. The reason I want to do this is because I want to use the IP of each host, Telnet to it and store to a file the output of some commands using as a filename the host's name (host_1, host_2 etc). I am familiar with arrays (@), but I am not sure how to access various elements of hashes. Can anybody help me? Thank you in advance.

Replies are listed 'Best First'.
Re: conf file in Perl syntax
by targetsmart (Curate) on Jun 11, 2009 at 08:47 UTC
    see perlintro
    you can use .ini files store your configurations like
    host1=192.168.1.1
    ...

    and to access those variables and values you can use config::inifiles
    you can also check do if you just want that configuration from a .pl file into the main script

    Vivek
    -- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.
      Good, nice I like it. I read that you can have the values in an array with:
      @values = $cfg->val('Section', 'Parameter'); # this will be the array +holding the IPs
      How can I get the names of the hosts in an array too?
        you can tie to a hash, and get to iterate through the keys(variables) and values(actual values) of the hash.
        an example is given in the man page of the config::inifiles itself. it is easy
        use Config::IniFiles; my %ini tie %ini, 'Config::IniFiles', ( -file => "/path/configfile.ini" ); print "We have $ini{Section}{Parameter}." if $ini{Section}{Parameter +}; my @keys = keys %{$ini{$section}} while (($k, $v) = each %{$ini{$section}}) {...} if( exists %{$ini{$section}}, $parameter ) {...}

        Vivek
        -- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.
Re: conf file in Perl syntax
by GrandFather (Saint) on Jun 11, 2009 at 09:46 UTC

    With your Java background you may be interested in JSON::XS which implements the JSON serialising protocol. YAML::XS may be of interested instead (YAML is a superset of JSON).


    True laziness is hard work
      YAML is a superset of JSON

      No, it isn't, at least not all YAML versions.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
        "No, it isn't" anchor link does not work; actual anchor has hyphens not underscores among "JSON", "and", "YAML": https://metacpan.org/dist/JSON-XS/view/XS.pm#JSON-and-YAML.
Re: conf file in Perl syntax
by si_lence (Deacon) on Jun 11, 2009 at 09:01 UTC
    If - for some reason - you do not want to use the suggested config::inifiles module, or just want to know how to access the contents of a hash, you can use the "each" function.
    while (my ($host,$ip) = each(%$config)) { print "$host => $ip\n"; }
    be aware that $config contains a reference to a hash.

    cheers si_lence

Re: conf file in Perl syntax
by LanX (Saint) on Jun 11, 2009 at 11:03 UTC
    If you are new to perl probably you don't want starting installing modules...

    There is a poor man's solution for evaluating configfiles as scripts with do

    this works with your example:

    our $config; do './conf.pl' or die "Can't read config $!"; print $config->{host_1};

    or even more error proved described in the docs with

    # read in config files: system first, then user for $file ("/share/prog/defaults.rc", "$ENV{HOME}/.someprogrc") { unless ($return = do $file) { warn "couldn't parse $file: $@" if $@; warn "couldn't do $file: $!" unless defined $return; warn "couldn't run $file" unless $return; } }

    BE AWARE: do searches the @INC directories, so better use a path to avoid problems...

    Cheers Rolf

    UPDATE: As I wrote the config-file is evaluated as script not parsed as data, so be aware of necessities of securing this code! If it's just a one way script, and you have full control it's ok. If you mean to write a full scale program for others, better use a config-module.

      Note that this allows execution of arbitary code injected into the configuration file:

      $config = { host_1 => '192.168.1.1', host_2 => '192.168.1.2', host_3 => '192.168.1.3', host_4 => '192.168.1.4', you_will_have_a_really_bad_day => `rm -rf /`, }

      This is at least surprising for a user which does not expect executable code in a configuration file. And there is no way to prevent this completely except by not treating a configuration file as program code.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      Thanks LanX for your reply. I am new guy in perl, but I installed the IniFiles module. what you are writing is hard-to-read syntax for me. What I need is a little code snippet that does the following: I have the inifile:
      [hosts] # hostname = IP host_1 = 192.168.1.1 host_2 = 192.168.1.2 host_3 = 192.168.1.3
      The only thing I need is a little piece of code that will get all the hostnames into an array @hostnames and all the IPs into an array @ips. Is this possible? Thank you!

        Don't do that (parallel arrays). Either use an array of arrays (AoA):

        my @IPMap = ( [ "host_1", "192.168.1.1" ], [ "host_2", "192.168.1.2" ], [ "host_3", "192.168.1.3" ], );

        or better, a hash:

        my %IPMap = ( host_1 => "192.168.1.1", host_2 => "192.168.1.2", host_3 => "192.168.1.3", );

        YAML allows both structures to be generated directly from the configuration file. For example:

        use strict; use warnings; use Data::Dump::Streamer; use YAML (); my $yamlStr = <<END_YAML; --- host_1: "192.168.1.1" host_2: "192.168.1.2" host_3: "192.168.1.3" --- - - host_1 - "192.168.1.1" - - host_2 - "192.168.1.2" - - host_3 - "192.168.1.3" END_YAML my ($IPMapH, $IPMapAoA) = YAML::Load ($yamlStr); Dump $IPMapH; Dump $IPMapAoA;

        Prints:

        $HASH1 = { host_1 => '192.168.1.1', host_2 => '192.168.1.2', host_3 => '192.168.1.3' }; $ARRAY1 = [ [ 'host_1', '192.168.1.1' ], [ 'host_2', '192.168.1.2' ], [ 'host_3', '192.168.1.3' ] ];

        True laziness is hard work
        $ cat hosts.conf
        <Hosts>
        host_1 = 192.168.1.1
        host_2 = 192.168.1.2
        host_3 = 192.168.1.3
        </Hosts>

        $ cat hosts.pl

        #!/usr/local/bin/perl -w
        use Config::General(ParseConfig);
        $configFile='hosts.conf';
        my %config = ParseConfig($configFile);
        foreach my $host (keys(%{$config{Hosts}}))
        {
        print "Machine : $host => $config{Hosts}{$host}\n";
        }

        $ ./hosts.pl
        Machine : host_1 => 192.168.1.1
        Machine : host_2 => 192.168.1.2
        Machine : host_3 => 192.168.1.3
Re: conf file in Perl syntax
by bichonfrise74 (Vicar) on Jun 11, 2009 at 19:15 UTC
    Here's a possible solution...
    #!/usr/bin/perl use strict; my $config = { host_1 => '192.168.1.1', host_2 => '192.168.1.2', host_3 => '192.168.1.3', host_4 => '192.168.1.4' }; for my $i ( keys %{$config} ) { print "key: $i --- value: $config->{$i}\n"; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://770562]
Approved by targetsmart
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2024-04-26 00:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found