Hi I have written yet another Linux config setting program. It works but I am seeking advice in improving it. This one reads network settings from an input file. The file is generated by an application that accepts user entries to a GUI. The entries are fully checked to ensure they are within valid ip ranges before they are saved to the file. This programme will rarely run as a Systemd service only when the input file is changed by the user. Readability and maintainability are more important to me that speed or brevity. The input file looks like this:
#IP Configuration #Fri Aug 27 16:07:40 NZST 2021 routers=192.130.1.1 interface=eth0 domain_name_servers=8.8.8. 8.8.1.1 ip_address=192.130.1.10/24
The target configuration file is dhcpcd.conf. The cut down version of the file looks like this:
#static domain_name_servers=192.168.1.1 # fallback to static profile on eth0 #interface eth0 #fallback static_eth0 ### Static LAN IP profile profile static_eth0 static ip_address=192.130.1.10/24 static routers=192.130.1.1 static domain_name_servers=8.8.8. 8.8.1.1 # fallback to static profile on eth0 interface eth0 fallback static_eth0 # Access Point Static interface mimirbox wlan0 interface wlan0 static ip_address=192.130.3.10/24 nohook wpa_supplicant
The target section is the static IP LAN profile, and nothing else. I have written a programme that basically is divided into 2 sections:
- reads the input file into a hash.
- does a find and replace on the dhcpcd config file.
The programme works but it is a lot longer that it probably should be.
The programme is as follows:

#!/usr/bin/perl use strict; use warnings; use Tie::File; use feature "switch"; no warnings 'experimental'; # Declare constants use constant false => 0; use constant true => 1; # Declare variables my $ip_filename = '/home/mimir/mb_ip.cfg'; # The ip info entered by t +he user into the GUI my $dhcpcd_filename = '/home/mimir/d.conf'; # The dhcp configuration f +ile to be written to #my $dhcpcd_filename = '/etc/dhcpcd.conf'; # A hash of config parameters to be updated in order # of how they should be saved. # Initiate with reasonable start values. my %ip_params = ( interface => "usb0", ip_address => "1.1.1.0", routers => "127.0.0.0", domain_servers => "1.1.1.1"); my $ip_line; # whole parameter line my @ip_fields; # parameter fields in a line # The list of saved user param variables tie my @ip_array, 'Tie::File', $ip_filename or die "Cannot tie file '$ip_filename': $!"; ########### Get param values from the GUI input file mb_ip.cfg ### Read the values from mb_ip.cfg and save to a hash for $ip_line (@ip_array) { @ip_fields = split /=/, $ip_line; # get the parameter name and val +ue given ($ip_fields[0]){ when ( /interface/ ) { $ip_params{'interface'} = $ip_fields[1]; } when ( /ip_address/ ) { $ip_params{'ip_address'} = $ip_fields[1]; } when ( /routers/ ) { $ip_params{'routers'} = $ip_fields[1]; } when ( /domain_name_servers/ ) { $ip_params{'domain_servers'} = $ip_fields[1]; } default { print "no match to params\n\n" } } } print "Network parameters loaded into the array \n" +; for(keys %ip_params){ print(" $_ is $ip_params{$_}\n"); } untie @ip_array; ########### Find the lines in the config file to be replaced. # Find the required interface section # Initiate the boolean variables that only change one parameter # in the config file section. # When all are found and changed, jump out. my $isFoundInterface = false; my $isFoundIP = false; my $isFoundRouters = false; my $isFoundDNS = false; # The config file to search and replace variables tie my @dhcpcd_array, 'Tie::File', $dhcpcd_filename or die "Cannot tie file '$dhcpcd_filename': $!"; print " \n\n\n"; # Find and replace the config lines for $ip_line (@dhcpcd_array){ print "$ip_line\n"; # look for 'profile static_eth0' that marks start of the section if ( $ip_line =~ /^.*profile\s*static_$ip_params{'interface'}\s*/ ) + { $isFoundInterface = true; # Found the first line of the sectio +n. print "############## Found profile line\n" ; next; # Jump to the next line in the file. } # When the profile interface section is found, look for the parameters + to change if ( $isFoundInterface == true ) { given ($ip_line){ when ( /^.*static\s*ip_address=/ ) { $ip_line = " static ip_address=$ip_params{'ip_address'} +"; $isFoundIP = true; } when ( /^.*static\s*routers=/ ) { $ip_line = " static routers=$ip_params{'routers'}"; $isFoundRouters = true; } when ( /^.*static\s*domain_name_servers=/ ) { $ip_line = " static domain_name_servers=$ip_params{'dom +ain_servers'}"; $isFoundDNS = true; } default { if ($isFoundInterface and $isFoundIP and $isFoundRouters and $isFoundDNS ) { last; } #stop searching the co +nfig file when changes all done. } } } print "isIP : $isFoundIP\n"; print "isRouters : $isFoundRouters\n"; print "isDNS : $isFoundDNS\n\n"; print "looking for the ip config params\n"; } untie @dhcpcd_array;

Note: The program still includes debug print statements. None of the ip addresses are actually used by me. I looked through the CPAN library and could not find anything that precisely suits my needs. I don't do much perl programming so there is a lot I don't know.
I am seeking constructive feedback on my programme.

Dazz

In reply to Yet another config file editing programme : Tell me how to make it better ! by dazz

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.