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

I am working on this PERL script and had all these sections working last night, but this morning I must have touched something by mistake because now the script has a strange newline getting inserted and it is blowing up the script.

This script is reading a file with 4 hostnames in it. It performs great for the 1st host on the list, but subsequent hostnames get the newline issue. Here is my output:

############################ Accessing 'HOSTFILE' SERVER: [xxxxxx.black. +lab.com] Operating System is: [Linux] System Platform is: [RedHat] Running on system: [xxxxxxx] >>> IP6 Device: eth0 is using: xx::219:xx:xxxx:xx/64 address >>> IP4 Device: eth1 is using: xx.xxx.xx.xxx address Mask: xxx.xxx.xxx.xxx Broadcast: xxx.xx.xx.xxx >>> IP6 Device: eth1 is using: xx:80c0:xx:xx:xx:xxxx:feee:xxxx/64 add +ress /etc-test/sysconfig/network-scripts/ifcfg-eth1 /etc-test/sysconfig/network-scripts/ifcfg-eth0 /etc-test/resolv.conf ############################ Accessing 'HOSTFILE' SERVER: [xxxx-xxxx.xxx +.xxx.xxxx.com ]

See how the second hostname has a ] on the next line!!!

This script is a .pl that calls a .pm. I will try to add the content of both files here below...

THE .PL FILE CODE

open (FILE, '<', 'hostfile2') or die "Could not open 'hostfile' : $!"; my @SERVERS = <FILE>; #print "AJAY <@SERVERS>\n"; foreach $server (@SERVERS) { #print "[$server]\n"; chomp($server); print "Accessing 'HOSTFILE' SERVER: [$server]\n"; my $opsys = getOS($server, $user, $password); print "Operating System is: [$opsys]\n"; my $pform = getPlatform($server, $user, $password, $opsys); print "System Platform is: [$pform]\n"; my $host = getHost($server, $user, $password); print "Running on system: [$host]\n"; my $nic; my @files; for $nic (getNetworkInfo($server, $user, $password, $pform)) { if (defined $nic->{ip}) { print ">>> IP4 Device: $nic->{device} is using: $nic->{ip} ad +dress\n" . "\tMask: $nic->{mask}\n" . "\tBroadcast: $nic->{bcast}\n"; } if (defined $nic->{ip6}) { print ">>> IP6 Device: $nic->{device} is using: $nic->{ip6} add +ress\n"; } push(@files, getPlatformFiles($pform, $nic)); } my %hash = map { $_ => 1 } @files; @files = keys %hash; foreach my $file (@files) { print "$file\n"; } }

THE .PM FILE CODE

sub getOS { my ($servername_in, $user_in, $password_in) = @_; #print "DEBUG [$servername_in][$user_in][$password_in]\n"; open(INPUTA,"ssh -q $user_in\@$servername_in $cmd1; echo $password +_in |") || die "command $cmd1 failed\n"; my $os = <INPUTA>; close INPUTA; chomp($os); #print "DEBUG [$os]\n"; return $os; } sub getPlatform { my ($servername_in, $user_in, $password_in, $opsys_in) = @_; my $platform; if ($opsys_in =~ /Linux/) { { my ($file, $var1, $var2); local $/ = undef; #undef the input rec seperato +r (newline), slurp file into a scalar, read entire file at once open(OUTPUTA, "ssh -q $user_in\@$servername_in $cmd3; echo + $password_in |") || die "command $cmd3 failed\n"; $file = <OUTPUTA>; close OUTPUTA; chomp($file); #print ">>>>>>>>>>>> FileContent is: [$file]\n"; if ( $file =~ /^(Red) (Hat)/ ) { ($var1, $var2) = ($1, $2) or next; $platform = "$var1$var2"; #print "$var1$var2\n"; last; } elsif ( $file =~ /\bWelcome to ([\w.]+)/ ) { ($var1) = ($1) or next; $platform = "$var1"; #print "$var1\n"; last; } elsif ( $file =~ /^(Ubuntu)/ ) { ($var1) = ($1) or next; $platform = "$var1"; #print "$var1\n"; last; } else { print "Operating System not supported in this script\n +"; } } } elsif ($opsys_in =~ /SunOS/) { $platform = "Solaris"; #print "DEBUG [$pform]\n"; } chomp($platform); return $platform } sub getHost { my ($servername_in, $user_in, $password_in) = @_; open(INPUTB,"ssh -q $user_in\@$servername_in $cmd2; echo $password +_in |") || die "command $cmd2 failed\n"; my $hn = <INPUTB>; close INPUTB; chomp($hn); #print "DEBUG [$hn]\n"; return $hn; } sub getNetworkInfo { my ($servername_in, $user_in, $password_in, $pform_in) = @_; my @nics; my $ifconfig; if ($pform_in eq "RedHat") { undef $/; open(OUTPUTB, "ssh -q $user_in\@$servername_in $cmd4; echo $pa +ssword_in |") || die "command $cmd4 failed\n"; $ifconfig = <OUTPUTB>; close OUTPUTB; chomp($ifconfig); for (split /(?<=\n)(?=\w)/, $ifconfig) { my %nic; ($nic{device}) = $_ =~ /^(eth\d)\s/ or next; if (/\binet addr:([\d.]+)\s.+?:([\d.]+)\s.+?:([\d.]+)/) { $nic{ip} = $1; $nic{bcast} = $2; $nic{mask} = $3; #print "Device: $nic{device} has the IP Address of $ni +c{ip}\n\tMask: $nic{mask}\n\tBroadcast: $nic{bcast}\n"; } if (/^\s+ inet6 addr:\s*(\S+)/m) { $nic{ip6} = $1; #print "Device: $nic{device} also has IPv6 address of +$nic{ip6}\n"; } push @nics, \%nic; } }elsif($pform_in eq "Solaris") { undef $/; open(OUTPUTC, "ssh -q $user_in\@$servername_in \"$cmd5\"; echo + $password_in |") || die "command \"$cmd5\" failed\n"; $ifconfig = <OUTPUTC>; close OUTPUTC; chomp($ifconfig); for (split /(?<=\n)(?=\w)/, $ifconfig) { my %nic; ($nic{device}) = $_ =~ /^(fjgi\d):\s/ or next; if (/\binet ([\d.]+)\s\w+\s([\w]+)\s\w+\s([\d.]+)/) { $nic{ip} = $1; $nic{mask} = $2; $nic{bcast} = $3; #print "Device: $nic{device} has the IP Address of $ni +c{ip}\n\tMask: $nic{mask}\n\tBroadcast: $nic{bcast}\n"; } if (/^\s+ inet6\s*(\S+)/m) { $nic{ip6} = $1; #print "Device: $nic{device} also has IPv6 address of +$nic{ip6}\n"; } push @nics, \%nic; } }elsif ($pform_in eq "SUSE") { undef $/; open(OUTPUTD, "ssh -q $user_in\@$servername_in $cmd4; echo $pa +ssword_in |") || die "command $cmd4 failed\n"; $ifconfig = <OUTPUTD>; close OUTPUTD; chomp($ifconfig); for (split /(?<=\n)(?=\w)/, $ifconfig) { my %nic; ($nic{device}) = $_ =~ /^(eth\d)\s/ or next; if (/\binet addr:([\d.]+)\s.+?:([\d.]+)\s.+?:([\d.]+)/) { $nic{ip} = $1; $nic{bcast} = $2; $nic{mask} = $3; #print "Device: $nic{device} has the IP Address of $ni +c{ip}\n\tMask: $nic{mask}\n\tBroadcast: $nic{bcast}\n"; } if (/^\s+ inet6 addr:\s*(\S+)/m) { $nic{ip6} = $1; #print "Device: $nic{device} also has IPv6 address of +$nic{ip6}\n"; } push @nics, \%nic; #Returning an list of hashrefs } }elsif($pform_in eq "Ubuntu"){ undef $/; open(OUTPUTE, "ssh -q $user_in\@$servername_in $cmd4; echo $pa +ssword_in |") || die "command $cmd4 failed\n"; $ifconfig = <OUTPUTE>; close OUTPUTE; chomp($ifconfig); for (split /(?<=\n)(?=\w)/, $ifconfig) { my %nic; ($nic{device}) = $_ =~ /^(eth\d)\s/ or next; if (/\binet addr:([\d.]+)\s.+?:([\d.]+)\s.+?:([\d.]+)/) { $nic{ip} = $1; $nic{bcast} = $2; $nic{mask} = $3; #print "Device: $nic{device} has the IP Address of $ni +c{ip}\n\tMask: $nic{mask}\n\tBroadcast: $nic{bcast}\n"; } if (/^\s+ inet6 addr:\s*(\S+)/m) { $nic{ip6} = $1; #print "Device: $nic{device} also has IPv6 address of +$nic{ip6}\n"; } push @nics, \%nic; #Returning an list of hashrefs } } #use Data::Dumper; #print Dumper(\$nics); #print Dumper(\@nics); #print Dumper(\%nics); return @nics; } sub getPlatformFiles { my ($plat_in, $nic_in) = @_; my @list; if ($plat_in =~ /RedHat/) { push (@list, "/etc-test/resolv.conf"); push (@list, "/etc-test/sysconfig/network-scripts/ifcfg-$nic_i +n->{device}" ); } return @list; }

Replies are listed 'Best First'.
Re: Getting a funny newline that was not there before
by moritz (Cardinal) on Mar 25, 2010 at 18:33 UTC
    but this morning I must have touched something by mistake

    This is a good time to start looking in your version control system what changes you did this morning.

    You don't have one? It's high time to start using one. It's quite easy, and really worth the (small) effort you have to put into it initially.

    Anyway, I suspect that problem is that you undef $/ globally, so chomp($server) does not do what you expect it to.

    Perl 6 - links to (nearly) everything that is Perl 6.

      Thank you. So should I change the code to local $/ = undef;

        And get a version control system, and actually use it. That's much more important in the long run. See for example this introduction for a free version control system with little installation effort.
        Perl 6 - links to (nearly) everything that is Perl 6.
Re: Getting a funny newline that was not there before
by crashtest (Curate) on Mar 25, 2010 at 18:46 UTC

    I was going to guess that you might have windows line-endings in your hostfile2 - which would also give you problems - but I think moritz has probably nailed it with his comment.

    Replace the four instances in getNetworkInfo where you globally undef $/ to do so with just local effect:

    # undef $/; # global effect! # instead: local $/ = undef; # local effect

    It also appears that you're not running under strict or warnings (unless you've snipped that from your post). You really should look into that.

Re: Getting a funny newline that was not there before ([OT] shuffle)
by toolic (Bishop) on Mar 26, 2010 at 00:49 UTC
    This has nothing to do with your newline problem.

    I happened to notice this curious snippet in your code:

    my %hash = map { $_ => 1 } @files; @files = keys %hash;
    Are you intentionally using the intermediate hash to reorder your @files array? I can find no other usage of your %hash variable in your code. If so, List::Util::shuffle will provide more randomness from run-to-run, and it would also make the intent of your code more evident:
    use List::Util qw(shuffle); @files = shuffle(@files);
      Are you intentionally using the intermediate hash to reorder your @files array?

      He could be de-duping the list.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Excellent point. I guess this demonstrates the value of giving variables meaningful names. If %hash had been named %seen or %uniq, then the intent would be much clearer.

      I am using the hash to remove duplicate entries from the list.