0

I have enhanced the code from the question I posted before:

My code is:

DIR="$1"


if [ -e "$DIR" ]

then

     echo -n "total directories:" ; find $DIR -type d | wc -l

     echo -n "total files:" ; find $DIR -type f | wc -l
else
if [ -f "$DIR" ]
then
    echo " Directory doesn't exist"

else
     echo  " please pass correct arguments"
fi
fi

This code gives output when I execute ./countfiledirs or countfiledirs jhfsakl :

sreekanth@sreekanth-VirtualBox:~$  ./countfiledirs 
 please pass correct arguments
sreekanth@sreekanth-VirtualBox:~$  ./countfiledirs ffff
 please pass correct arguments

I want output when i executed the script name ./countfiledirs as:

please pass correct arguments

and for ./countfiledirs ffff as:

directory doesn't exists

I have another problem with the code when I exceuted script ./countfiledirs /usr/share. It's not giving the actually no of directories and subdirectories for the path which I have given. Instead of 3 directories it's showing 4

  • If the answers you received to your previous question answered that question, please accept one. That way, the question can be marked as solved. – terdon May 05 '15 at 13:31
  • @Buddha please look at the answer I have already given you in your first of these multiple almost-duplicates. If you start with working code you will benefit tremendously when you step out to improve and increase its functionality. – Chris Davies May 05 '15 at 13:39

2 Answers2

2

The test [ -f "$DIR" ] is true if $DIR exists and is a file. That's not what you want at all. As I suggested in your previous question, you should use $# to check whether an argument has been passed. Then you can use -e to check whether that argument exists.

The next issue is that find will also list ., the current directory. You can use -mindepth 1 to avoid this with GNU find:

DIR="$1"

if [ $# -lt 1 ]
then
    echo "Please pass at least one argument" && exit   
fi
if [ -e "$DIR" ]
then
     echo -n "total directories:" ; find "$DIR" -mindepth 1 -type d | wc -l
     echo -n "total files:" ; find $DIR -type f | wc -l
else
      echo "Directory doesn't exist"
fi

You could also condense the above to (though this version does not differentiate between a directory that doesn't exist and one that is a file, not a directory):

dir="$1"
[ $# -lt 1 ] && echo "Please pass at least one argument" && exit
[ -d "$dir" ] && printf "total directories: %s\ntotal files:%s\n" \
              $(find "$dir" -type d | wc -l) $(find "$dir" -type f | wc -l) ||
    printf "%s\n" "There is no directory named '$dir'."
terdon
  • 242,166
  • Is it possible to write the entire code in one if statement ? – buddha sreekanth May 05 '15 at 13:46
  • Yes - just check that the directory exists and is a directory first, exiting if this condition fails. The rest of it then need not be inside a conditional. The rest could be inside the "else" portion, if you really liked indenting things. – Christopher Peterson May 05 '15 at 14:05
  • @buddhasreekanth not really. You are checking different things and want three separate outcomes depending on the situation. See updated answer for a more concise version. – terdon May 05 '15 at 14:09
1

As you have it in your last conditional, you're checking if $DIR refers to a "regular file." That is, not a directory. So it is always failing (since you are always giving directories, presumably) and printing " please pass correct arguments".

As for the directory counts being "incorrect," they aren't. If you were to run the find command manually as it is in the script you would see that it returns the directory at the root of its search as well as its subdirectories. So you can either know that it is counting the given directory, or get the answer you wanted by simply decrementing the count after calling find.

This seems to be what you're looking for. Bear with me; I've verified that this works, but I am no BASH expert.

DIR="$1"

if [ ! -d "$DIR" ]  #If not a directory, 
then
    echo " please pass correct arguments"
    exit 1
fi

# We know for sure $DIR is present and a directory, so we know
# that it will show up in the find results for type d. Decrement.
echo -n "total directories:" $(($(find $DIR -type d | wc -l) - 1))
echo
echo -n "total files:" ; find $DIR -type f | wc -l