Checking for existence of a directory (UNIX PERL 5)

I'm writing a little util to check on the utilisation of users using perl

I ave no problem extraction the user information including the path to thier home directory.

I can extract the amount of space used using du.

But my code for checking whether the home directory exists works apart from at the start of a run du runs on an inaccessable dir I can't see why could any one point me in the right direction?

Listing
------------------------------------

#----------------------------------------------------------------------------------------------------
#      Program      : User Reporting Tool
#      Author       : Stephen Smith
#      Rev      : 1.2
#----------------------------------------------------------------------------------------------------

%UDetailHash       = ();                         # Declare an empty hash for holding the user details
                                    # Users will be referred to by user name

$UserName      = '';                        # Variable to hold the current users name

setpwent();                              # Move to the start of the user database

while( @DetailArray = getpwent() ) {            # Loop through the lines of user data stopping when
                                    # no data remains

      $UserName = shift(@DetailArray);      # Remove the user name from the array of user data
      $Temp = 1;                        # Status flag
      opendir(DIR,@DetailArray[6]) or $Temp = 0; # Try to open directory if failed set temp = 0
      if ($Temp > 0) {                  # If Temp > 1 then we need to get the usage
            closedir(DIR);                  # Close the directory handle

            $Temp = `du -s -b @DetailArray[6]`;       # Execute the disk usage command using the users
                                          # home dir to find out file usage
            @DUResults = split(/\s+/,$Temp);      # Split the returned data into an array
            @DetailArray[8] = @DUResults[0];      # Put the space used into the user details array
            } else {                        # If the directory did not exist
            @DetailArray[8] = 0;                  # Set disk space used to 0
            }

# This is confusing bit:
# For the current user held in $UserName create a new hash entry and store in the hash entry a
# reference to an anonymous array that holds the contents currently held in @DetailArray
# (User Details)

      push( @{ $UDetailHash{$UserName} }, @DetailArray );
      }

# We now have a hash %UDetailHash that holds all the details of each user referenced by username
# to output some of the details in username order we will sort the keys of the hash and use them
# in a for each loop

foreach $UserName (sort keys %UDetailHash) {

      print "$UserName: @{$UDetailHash{$UserName}}\n";

      }

-----------------------------------

Sorry its messy but I'm still hackking around with it.

LVL 1
Steves2001Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

thoellriCommented:
Can you show us the error message 'du' reports?

And by the way: You should address indiviual array-elements as 'scalars' which is what they really are. Using the @ syntax gets a 'slice' from the array of size one which happens to be the same thing in your case, but "looks weird".

So @array[6] = $array[6] instead.

Tobias
0
guadalupeCommented:
I'm not sure if I got it but try this.  Put the du command inside a conditional that check first if the dir exists:

if (-d "$path/$file")
{

#du
}

remember to use the double quotes as file checks like this and -e for existence seem to require them even when it is evaluted against variables.
0
Steves2001Author Commented:
Many thanks I found the problem, it was my own fault, I wasn't paying attention to the contents of the passwd file, what was happening was I have a default user on RedHat 6.1 of nobody which was assigned to the root directory, when du accessed this user it was encountering a directory created by a running process and was unable to access it hence the error.

Tobias,

thank you for the comment, I am still learning and I had made an error on that line, many thanks.

quadalupe your method of testing is cleaner and more readable, I ended up using stat and doing -d && -e tests to check for existence and that it was a directory.

Although neither of you solved the problem you have both given me some very useful pointers that have helped me.

Thank you very much.


Stephen Smith

I don't know if ee have resolved the problem of splitting points but feel free to work it out between yourselves and answer the question.

If you have time perhaps you might just check this line, it was from the o'reilly perl cookbook but in their example the @ sign on the detail array was a dollar that didn't allow me to access the array once stored have I used the correct notation for storing and array reference in a hash, it seems to work.


push( @{ $UDetailHash{$UserName} }, @DetailArray );
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

thoellriCommented:
Steve,

regarding the push-question: Look up the documentation for 'push' (using 'perldoc -f push') and you will find:

  push ARRAY,LIST

  Treats ARRAY as a stack, and pushes the values of LIST
  onto the end of ARRAY.  The length of ARRAY increases by the length of
  LIST.

Where the cookbook used a scalar ($abc) they actually used a one-element list. You code makes sense and is pefectly legal.

Tobias
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Steves2001Author Commented:
Thanks

Answer for the points if you want.

Stephen Smith
0
guadalupeCommented:
If you want to split the points just change the point value to 50 award to either of use and post a dummy quest and the other will answer...
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Perl

From novice to tech pro — start learning today.