Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

File reading with hashes

by Bindo (Acolyte)
on Aug 08, 2013 at 06:35 UTC ( #1048485=perlquestion: print w/ replies, xml ) Need Help??
Bindo has asked for the wisdom of the Perl Monks concerning the following question:

Gentlemen I have a file called "MY_FILE" with a certain string(BASEPORT=1000) along with other information, placed on all system user's home directory. I want to have the name of the system user and the value that is mentioned under BASEPORT parameter to be printed on to the screen in following manner

User1 --> 1000

User2 --> 5000

I get the following error with what I have attempted so far

readline() on closed filehandle FH2 at ./base_ports.pl line 12, <FH2> line 3103

Following is the script

my %ARR1 = uid(); foreach my $TAB (keys %ARR1) { if (-e "$ARR1{$TAB}/MY_FILE") { open (FH2, "<$ARR1{$TAB}/MY_FILE"); while (my $STRING = <FH2>) { if ($STRING =~ /BASE_PORT=(\d+)/) { my $STRING = $1; print "$TAB --> $STRING"; } } } } sub uid { my %UID_PATH; open (FH1, "</etc/passwd") || die "Can't Open : $!"; while (<FH1>) { my @UID = split (/:/, $_); if ($UID[2] > 500) { my $USER = "$UID[0]"; #%UID_PATH = ("$USER" => '$UID[5]'); $UID_PATH{$USER} = "$UID[5]"; } } return %UID_PATH; }

Please could you help. Please feel free to modify the code. Many thanks in advance

.

/Bindo

Comment on File reading with hashes
Download Code
Re: File reading with hashes
by mtmcc (Hermit) on Aug 08, 2013 at 07:07 UTC
    Have you checked that your open for FH2 is successful?

    For a start I'd change line 4 to:

    open (FH2, "<", "$ARR1{$TAB}/MY_FILE") or die "couldn't open FH2: $!\n +";

      Thanks. I did check and there were no problems.

Re: File reading with hashes
by rnewsham (Hermit) on Aug 08, 2013 at 07:17 UTC

    I do not get an error from your code. I have made a few modifications to improve layout and readability which you may find interesting. I have not really changed the functionality other than adding a die on being unable to open FH2 as suggested by mtmcc.

    use strict; use warnings; my %users = %{user_paths()}; foreach my $user (keys %users) { if (-e "$users{$user}/MY_FILE") { open (FH2, "<$users{$user}/MY_FILE") or die "could not open $u +sers{$user}/MY_FILE $!"; while (my $line = <FH2>) { if ($line =~ /BASE_PORT=(\d+)/) { print "$user --> $1"; } } } } sub user_paths { my %users; open (FH1, "</etc/passwd") || die "Can't Open : $!"; while (<FH1>) { my @user = split (/:/); if ( $user[2] > 500 ) { $users{$user[0]} = "$user[5]"; } } return \%users; }

      Thank you very much for triying to help me out. However I now get a permission error. "could not open /x02/bee/MY_FILE Permission denied at ./base_ports.pl line 9, <FH2> line 3103. but when I tried to open the file before going on to the regex section it just works, As in it opens up the files on the screen

      my %users = %{user_paths()}; foreach my $user (keys %users) { if (-e "$users{$user}/MY_FILE") { open (FH2, "<$users{$user}/MY_FILE") or die "could not open $u +sers{$user}/MY_FILE $!"; while (my $line = <FH2>) { print $line; } } }

      Also I tried commented out the die function and tried to riun and then I get that same "readline" error. Any thoughts?

        can you open /x02/bee/MY_FILE from the command line with something like cat? What are the perms if you ls -l /x02/bee/MY_FILE? Does this match your user/group settings?

        Cheers,
        R.

        Pereant, qui ante nos nostra dixerunt!

        Can you try this version and see if any files are opened?

        #!/usr/bin/perl use strict; use warnings; # my $fname = '.profile'; my $fname = 'MY_FILE'; my %users = %{user_paths()}; for my $user (keys %users) { my $fh; if (open $fh, '<', "$users{$user}/$fname") { while (my $line = <$fh>) { if ($line =~ /BASE_PORT=(\d+)/) { print "$user --> $1"; } } } else { warn "couldn't open $users{$user}/MY_FILE $!"; } } sub user_paths { my %users; open my $fh, '<', "/etc/passwd" || die "Can't Open : $!"; while (<$fh>) { my @user = split (/:/); if ( $user[2] > 500 ) { $users{$user[0]} = "$user[5]"; } } return \%users; }

        Cheers,
        R.

        Pereant, qui ante nos nostra dixerunt!
Re: File reading with hashes
by kcott (Abbot) on Aug 08, 2013 at 07:26 UTC

    G'day Bindo,

    See the documentation for the open function. Follow the example for opening a file for reading using three arguments and dying with a useful message when the open fails. Just because the file exists (i.e. -e is TRUE), doesn't mean you can read it (i.e. -r is not necessarily TRUE).

    I'd also recommend you take a look at perlstyle: your code indentation is not at all logical which makes it hard to read and is a potential source or errors.

    -- Ken

      Greetings Ken. Thanks for the advice. Im still a beginner and yes I admit that there are lots of shortcomings in my code. Hope I will get better over time :)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1048485]
Approved by kcott
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (7)
As of 2014-12-25 09:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (159 votes), past polls