[Webinar] Streamline your web hosting managementRegister Today

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1111
  • Last Modified:

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?


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

  • 2
  • 2
  • 2
1 Solution
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.

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")


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


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 );
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.


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


  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

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

Steves2001Author Commented:

Answer for the points if you want.

Stephen Smith
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...

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 2
  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now