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

Hi I'm try in to check a number of ports against the etc/services file.

I have created an array of various ports

@myports qw( 21 22 23) open SERVICES_FILE, "<", "/etc/services" or die $!; foreach my $port (@myports) { print $port; } while (my @lines = <SERVICES_FILE>) { for my $line (@lines){ if ( my $port =~ m/$line/ ) { print "Match Found: $line"; } } } }

But Im getting errors

Use of uninitialized value $port in pattern match (m//) at ./get_services.pl line 48, <SERVICES_FILE> line 10774. Unknown verb pattern '' in regex; marked by <-- HERE in m/exp1 1021/tcp # RFC3692-style Experiment 1 (*) <-- HERE RFC4727 / at ./get_services.pl line 48, <SERVICES_FILE> line 10774.

any pointers for a newbie

Replies are listed 'Best First'.
Re: Port check - Services File
by stevieb (Canon) on Dec 02, 2015 at 16:39 UTC

    Note that if all you want to do is collect up the service name related to a port, Perl's got getservbyport:

    use warnings; use strict; my @ports = qw(21 22 23); my $protocol = 'tcp'; for (@ports){ my ($name, $alias, $num, $proto) = getservbyport($_, $protocol); print "$num: $name\n"; }
Re: Port check - Services File
by hippo (Archbishop) on Dec 02, 2015 at 15:37 UTC
    any pointers for a newbie

    Top pointer: use sane indenting. If you had then it would be much clearer that $port is out of scope when you use it at line 48.

    Try to provide an SSCCE. That way people can be better informed as to which of your 18 lines is line 48.

    Also, arbitrary lines of data such as may be found in /etc/services do not necessarily make valid regular expressions, therefore you should not attempt to use them as such. Consider using split or a pattern match to extract only the port number.

    There's no point in trying to analyse the comments in /etc/services, so skip them.

    Wrap your error text in <code> tags so that others can read them.

    HTH, Hippo

      many thanks, notes taken onboard

Re: Port check - Services File
by 1nickt (Canon) on Dec 02, 2015 at 15:28 UTC

    The code you posted doesn't compile. Please post a compiling code snippet and also a sample of what you have in /etc/services. (See Write-up formatting tips.)

    Here's a rewrite of your code with several comments so you can see what's different:

    ( Edit: as hippo points out below, it's not likely that your /etc/services file actually contains lines containing only port numbers. This example code does not address that issue, nor try to use regular expression matching; it's just an example of how to work through your two data sets. )

    #!usr/bin/perl use strict; # don't leave home without it use warnings; # same here! use 5.10.0; # so you can use say() my @ports = qw( 21 22 23 ); # make a hash from the array for easier lookup my %ports = map { $_ => 1 } @ports; # use a lexical variable for your filehandle open my $SERVICES_FILE, '<', '/etc/services' or die $!; # read one line at a time with while() while ( my $line = <$SERVICES_FILE> ) { # deal with new-line character at end of line chomp( $line ); # 'postfix if' simplifies syntax say "Match Found: $line" if $ports{ $line }; } # good practice to close filehandle close $SERVICES_FILE or die $!; # good practice to tell Perl when the program's done __END__

    The way forward always starts with a minimal test.

      many thanks, notes taken, will play now