I've been studying Perl for about a month so any advice is appreciated. I'm writing a script to simplify the CLI administration of GNU/Mailman. Everything's been working well up to this point, now when I test out the code it doesn't error out or anything but it seems to maybe loop endlessly on something.

I'm suspecting that it's line #154 which does:
foreach (@lists)...
foreach...
while...

I've spent an hour trying to figure this out and it's not popping out at me what's wrong. The Python commands I invoke in the subroutines all work, I've tested the commands themselves. The new code I added is from line#154 down, and each sub that gets invoked from there on.

This is a work in progress, but I'm trying to close up and finish each component then test, rinse repeat.

I apologize ahead of time, the code pasted on here looks quite ruffled. I'm using vim and pasting it into Window's Firefox.

The code:
#!/usr/bin/perl # use strict; use warnings; use File::Copy; my $choice = 999; # SOMETHING WAY OFF...JUST IN CASE # DEFINE THE FUNCTIONS ###################################################################### +############################## sub getlists { # GRAB THE LATEST LISTS ON THE SERVER my @locknloadlist = (); open(LISTLISTS, "/usr/lib/mailman/bin/list_lists -b|") || die +"Can't run program: $!\n"; while (<LISTLISTS>) { chomp($_); # THE NEWLINE AT THE END JACKS UP THE MAILM +AN PYTHON TOOLS push(@locknloadlist,$_); } return @locknloadlist; } sub exportconfig { # GRAB THE CONFIG FROM THE LIST SPECIFIED (my $currentlist, my $dirname) = @_; system("/usr/lib/mailman/bin/config_list -o ./${dirname}/${cur +rentlist}.config ${currentlist}"); print "\n\t$currentlist config saved...\n"; } sub exportmembers { # GRAB THE MEMBER ADDRESSES FROM THE LIST SPECIFIED (my $currentlist, my $dirname) = @_; # my $memberfilepath = $dirname . $currentlist . "\.emails"; my $memberlist = `/usr/lib/mailman/bin/list_members ${currentl +ist}`; open(MEMBERFILE, ">./${dirname}/${currentlist}.emails") || die + "\n\tUnable to write member file: $!\n"; print MEMBERFILE $memberlist; close(MEMBERFILE); print "\n\t$currentlist member addresses saved...\n"; } sub exportmods { # GRAB THE ADMIN ADDRESSES FROM THE LIST SPECIFIED (my $currentlist, my $dirname) = @_; my $modlist = `/usr/lib/mailman/bin/list_owners $currentlist`; open(ADMINFILE, ">./${dirname}/${currentlist}.admins") || die +"\n\tUnable to write admin file: $!\n"; print ADMINFILE $modlist; close(MEMBERFILE); print "\n\t$currentlist admin addresses saved...\n"; } sub importconfigs { # GRAB list, directory, config file & IMPORT (my $currentlist, my $dirname, my $configfile) = @_; system("/usr/lib/mailman/bin/config_list -i ${dirname}${config +file} $currentlist"); print "\n\t$currentlist config loaded...\n"; } sub importmembers { # GRAB list, directory, member list & IMPORT (my $currentlist, my $dirname, my $memberFile) = @_; system("/usr/lib/mailman/bin/add_members --regular-members-fil +e=${dirname}${memberFile} --welcome-msg=n --admin-notify=n $currentli +st"); print "\n\t$currentlist member addresses added...\n"; } sub importadmins { # GRAB list, directory, admin list & IMPORT (my $currentlist, my $dirname, my $adminFile) = @_; my @adminaddr = (); open(ADMINFILE, "<${dirname}${adminFile}") || print "\n\tCould +n't open $adminFile: $!\n"; while (<ADMINFILE>) { # GRAB THE ADDRESSES chomp($_); push(@adminaddr,$_); } close(ADMINFILE); open(NEWADMINFILE, ">${dirname}${currentlist}.tmp") || print " +\n\tCouldn't create ${dirname}${currentlist}.tmp: $!\n"; foreach my $address (@adminaddr) { # BREAK ADDRESSES U +P INTO "USERNAME[0] DOMAIN[1]" FOR NEXT STEP my @pieces = split('@', $address); print NEWADMINFILE "mlist.owner.append('$piece +s[0] at $pieces[1]')" # FUNKY PYTHON INPUT } close(NEWADMINFILE); system("/usr/lib/mailman/bin/config_list -i ${dirname}${curren +tlist}.tmp $currentlist"); unlink("${dirname}${currentlist}.tmp"); # WE DONT NEED THIS AN +YMORE print "\n\t$currentlist admin addresses added...\n"; } sub breakEmailAddress { # JUST IN CASE WE NEED IT my ($address) = shift(@_); my @components = split('@', $address); return @components; # @output = &breakEmailAddress('john@some.domain.com'); # print "Username is ", $output[0], "\nDomain is ", $output[1] +; } ###################################################################### +############################## # CLEAR THE SCREEN system $^O eq 'MSWin32' ? 'cls' : 'clear'; # READY STEADY GO! ###################################################################### +############################## while ($choice != 0) { my @lists = getlists(); print "\n\n"; print "\tWhat would you like to do?:\n"; print "\t" . "-" x 50 . "\n"; print "\t 1) Export list(s) (config, members, mods)\n"; print "\t 2) Import list(s) (config, members, mods)\n"; print "\t 0) Exit\n" . "\n"; print "\t\>"; chomp($choice = <>); if ($choice == 0) { # JUST IN CASE ;-p print "Bye!\n\n"; exit; } if ($choice == 1) { # EXPORT print "\n\tGetting current lists...\n"; @lists = getlists(); print "\tEnter directory name to create and du +mp files into (eg BACKUP): "; chomp(my $exportdirname = <>); mkdir($exportdirname, 0777) || die "\n +\tDIR make failed: $!\n"; foreach (@lists) { exportconfig($_, $exportdirname); exportmembers($_, $exportdirname); exportmods($_, $exportdirname); } } if ($choice == 2) { # IMPORT print "\n\tGetting current lists...\n"; @lists = getlists(); print "\tEnter the PATH (with trailing \'/\')w +here I can find exported files (eg ./backup/):\n\t\> "; chomp(my $importdirname = <>); # GET I +MPORT FILE LOCATION opendir(IMPORTDIR, $importdirname); my @importfiles = readdir(IMPORTDIR); closedir(IMPORTDIR); my @listconfigs = (); my @listmembers = (); my @listadmins = (); foreach my $file (@importfiles) { if ($file =~ /config/) { push(@listconfigs,$file); print "\n\tFound $file...\n"; } elsif ($file =~ /emails/) { push(@listmembers,$file); print "\n\tFound $file...\n"; } elsif ($file =~ /admins/) { push(@listadmins,$file); print "\n\tFound $file...\n"; } else { print "\n\t$file is not a val +id file to IMPORT.\n\n";} } foreach (@lists) { my $nextInLine = $_; foreach my $configFile (@listconfigs) +{ while ($configFile =~ /$nextIn +Line/) { importconfigs($nextInL +ine, $importdirname,$configFile); } } foreach my $memberFile (@listmembers) +{ while ($memberFile =~ /$nextIn +Line/) { importmembers($nextInL +ine, $importdirname, $memberFile); } } foreach my $adminFile (@listadmins) { while ($adminFile =~ /$nextInL +ine/) { importadmins($nextInLi +ne, $importdirname, $_); } } } } } print "Bye!\n\n"; exit;

The whole idea is to make a simple CLI menu that gathers data and runs mailman commands with inputs in the right places so ppl who don't use the software don't have to keep referencing my documentation when they administer the server it's on.

My primary goal with this post is to get past this current issue. Thanks in advance.


In reply to nested foreach siezing up somehow by grep65535

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.