user2786596
user2786596

Reputation: 145

Finding Directories and files

#for d in $DIRCOUNT
#do
#    DIRCOUNT=$[$DIRCOUNT+1]
#done


#for f in $FILECOUNT
#do
#    FILECOUNT=$[$FILECOUNT+1]
#done

#for r in $READ
#do
#    READ=$[$READ+1]
#done

#for w in $WRITE
#do
#    WRITE=$[$WRITE+1]
#done

#for e in $EXECUTABLE
#do
#    EXECUTE=$[$EXECUTE+1]
#done


for item in $LOCATION/* $LOCATION/.*
do
if  [ -f "$item" ]
 then
    FILECOUNT=$[$FILECOUNT+1]
 elif [ -d "$item" ]
 then
    DIRCOUNT=$[$DIRCOUNT+1]
 elif [ -r "$item" ]
 then
    READ=$[$READ+1]
 elif [ -w "$item" ]
 then
     WRITE=$[$WRITE+1]
 elif [ -e "$item" ]
 then
     EXECUTE=$[$EXECUTE+1]
fi
done

echo "Number of directories: " $DIRCOUNT
echo "Number of files: " $FILECOUNT
echo "Number of readable: " $READ
echo "Number of writble: " $WRITE
echo "Number of executable: " $EXECUTE

I want to find out the number of directories and files, and their types. I am new to this, i am not sure what do do with read write and executes. I actually don't know what is happening in the elif part, can someone please explain to me what i have done and what should i be doing?

Upvotes: 0

Views: 44

Answers (2)

D.Shawley
D.Shawley

Reputation: 59583

The largest problem with your if-elsif chain is that the entry's type (e.g., directory, file) is orthogonal to its mode (e.g., read, write, exec). You should use one chain of if statements that detect the entry type and a second set to process the mode.

for entry in $LOCATION/* $LOCATION/.*
do
    if [ -d "$entry" ]; then
        DIRCOUNT=$((DIRCOUNT + 1))
    elif [ -f "$entry" ]; then
        FILECOUNT=$((FILECOUNT + 1))
    elif [ -L "$entry" ]; then
        LINKCOUNT=$((LINKCOUNT + 1))
    elif [ -c "$entry" -o -b "$entry" ]; then
        DEVCOUNT=$((DEVCOUNT + 1))
    else
        UNKNOWNCOUNT=$((UNKNOWNCOUNT + 1))
    fi

    if [ -r "$entry" ]; then
        READABLECOUNT=$((READABLECOUNT + 1))
    elif [ -w "$entry" ]; then
        WRITABLECOUNT=$((WRITEABLECOUNT + 1))
    elif [ -x "$entry" ]; then
        ACTIONABLECOUNT=$((ACTIONABLECOUNT + 1))
    fi
end

A few things to note:

  • there are more types of directory entries than just files and directories. You also have device files (character & block special) and symbolic links. If you need to detect FIFOs, then you need to do that before the test for "file" (-f) since FIFOs are also normal files. A good reference to test(1) is essential here.
  • each entry has a set of associated modes (e.g., read, write, exec, set-uid, set-gid, sticky, etc.). A good reference to chmod(1) describes these in detail.
  • a more UNIX like approach would be to use find(1) and wc(1) to count the number of entries that have a particular attribute - find . -depth 1 -type f | wc -l will give you the number of "normal files" in the current directory.

Upvotes: 0

William Pursell
William Pursell

Reputation: 212404

There are several options w.r.t syntax:

test -f "$item" && : $((FILECOUNT++))
test -d "$item" && DIRCOUNT=$( expr $DIRCOUNT + 1 )

are two that I like. An else/if chain is probably not appropriate here, since you will never see an increment to READ, WRITE, or EXECUTE, and many files have several of those attributes.

Upvotes: 1

Related Questions