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

Hi,

I’m novice in Perl. I wrote the below Perl script. I’ve some issue with foreach or while loop and it doesn’t work as expected.

tmp/dl


group1
group2

/tmp/removemem
uid1
uid2


Alias for uid1:
uid1@example.com
uid.1@example.com

Alias for uid2:
uid2@example.com
2.uid@example.com

1. Go through each group from /tmp/dl list and get the members from that group using ldap
2. Go through the user from list /tmp/removemem and get the aliases for each from ldap
3. go through each member(from step 1) email and grep against the array of aliases.
4. If matched print else continue to the next member

group1
—————
a1@example.com
uid1@example.com

group2
—————
a2@example.com
uid2@example.com
2.uid@example.com
uid.1@example.com
#! /usr/bin/perl -w use Net::LDAP; open ( FH, "<", "/tmp/dls" ) or die "Could not open file... :$! \n"; open ( FH2, "<", "/tmp/removemem" ) or die "Could not open file... :$! + \n"; $ldap = Net::LDAP->new ( “ldap-master" ) or die "$@"; $mesg = $ldap->bind( dn => "uid=admin,ou=SysAccounts,dc=admin +,dc=local", password => “pass", ); while ( $dl = <FH> ) { chomp $dl ; $mesg = $ldap->search ( base => “dc=example, dc=com", filter => "mail=$dl", attrs => [ 'mgrprfc822mailmember' ], ); @entries = $mesg->entries; foreach $entry ( @entries ) { @members = $entry->get_value('mgrprfc822mailmember'); print "\n"; print "$dl\n"; print "Members are: @members\n"; foreach $member ( @members ) { while ( $curmem = <FH2> ) { chomp $curmem; print "\n$curmem\n"; $mesg2 = $ldap->search ( base => “dc=example, dc=com", filter => "uid=$curmem", attrs => [ 'mailLocalAddress' ], ); @entries2 = $mesg2->entries; foreach $entry2 ( @entries2 ) { @current = $entry2->get_value('mailLocalAddress'); print "\n File UID $curmem has following Aliases: @curren +t\n"; # } print "MATCH Starting\n"; if ( grep /^$member$/, @current ) { print "MATCHED: $member\n" ; } # } } } } } } $mesg = $ldap->unbind ;

Replies are listed 'Best First'.
Re: foreach/while loop help
by Anonymous Monk on Jul 12, 2015 at 23:19 UTC

    Aside from the typos (smart quotes) what is the problem?

    I see you have nested loops, this means you need more function

    I also see you have readline loop inside readline loop but with open outside the loops -- this means you definitely need more functions


      Thanks for your reply.
      The issue is , code isn't looping through each group and member from the list
      As you mentioned, the looping inside looping is confused, I guess and need more functions but don't know what it is.
      I'm just learning to write in Perl so definitely need more help to understand.

        The issue is , code isn't looping through each group and member from the list

        What loop is that?

        Why do you think it isn't looping, because data is missing, or ldap calls aren't returning data or ?

        The way to solve that problem is to eliminate everything from the code that isn't that loop, and solve only that loop, see Re^2: Perl Script and Re^4: Main logic of this script (summary/abstract/outline) (and parent/replies)

        So when I run your program through ppi-outline.pl I get

        so I might rewrite that as

        while( $dl = <FH> ){ my @entries = GetEntries( ... ); FudgeEntries( \@entries, $removememfilepath ); }

        Basicaly outline the program in terms of subroutines ( make more subs, don't develop allergy ) that actually run, even if that means making them stubs stubs by hardcoding the data, then one by one turn the stubs into real subs. Get running code first, then slowly improve that running code.

        is ldap-master temporarily offline? If you use stubs you can still develop your program .... and others who don't use ldap at all (or don't have an is ldap-master like yours) can help you

        Is the problem with GetMembers()? Only concentrate on getmembers ....

        Somewhere in your program you make an assumption about a function or some data that isn't true, so your program doesn't work the way you want it; all you have to do is find it, that gets easy with small subs

Re: foreach/while loop help
by u65 (Chaplain) on Jul 13, 2015 at 10:37 UTC

    And, aside from the other good advice above, you should add 'use strict;' after the shebang line ('#!/usr/bin/perl').

      Thank you for your valuable suggestions.

      I found the issue. When I open the file handle, I did close it so when it looked for the 2nd element from the list, there was nothing to match.
      Thank you again.