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

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 ./ 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



Replies are listed 'Best First'.
Re: File reading with hashes
by kcott (Chancellor) 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 :)

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 (Chaplain) 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 ./ 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?


        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; }


        Pereant, qui ante nos nostra dixerunt!

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1048485]
Approved by kcott
[Tanktalus]: I think I'm "out there" somewhere. I sure don't feel like I'm "here" right now. :S

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (7)
As of 2017-09-22 21:05 GMT
Find Nodes?
    Voting Booth?
    During the recent solar eclipse, I:

    Results (269 votes). Check out past polls.