I have written this code as part of some coursework, where we have to create a recursive file counter without using the find, du or -R commands. This appears to work but always returns hiddenfilecounter as 0. Is there any particular reason this is not working.#!/bin/shshopt -s dotglobdirectoryCounter=0fileCounter=0hiddenDirectoryCounter=0hiddenFileCounter=0listAllFiles()   {   local dir=$1   local file   local bn=$(basename $dir)   for file in $dir/*; do     if [[ $bn == .* ]]; then     let hiddenDirectoryCounter+=1     listAllFiles $file   elif [[ -f $file &&  $file == ^. ]]; then     ls -l $file     let hiddenFileCounter+=1   elif [[ -f $file ]];then     ls -l $file     let fileCounter+=1   elif [[ -d $file ]]; then     listAllFiles $file     let directoryCounter+=1        fi  done} listAllFiles $1echo File found: $fileCounterecho Directories found: $directoryCounterecho Hidden directories found: $hiddenDirectoryCounterecho Hidden files found: $hiddenFileCounter
How to detect if a file is hidden
bash;files
There are a few things wrong here. First, you are running /bin/sh when you actually want to run /bin/bash. Now, the part of your script that checks for hidden files iselif [[ -f $file &&  $file == ^. ]]; thenIf you run your script as foo.sh /home/foo, each $file will begin with /home/foo so not even hidden files will begin with dots. In addition, you can't use ^ with ==, it matches the beginning anyway (see here).Anyway, a working implementation of your script would be#!/usr/bin/env bashshopt -s dotglobdirectoryCounter=0fileCounter=0hiddenDirectoryCounter=0hiddenFileCounter=0listAllFiles()   {   local dir=$1   local file   local bn=$(basename -- $dir)   for file in $dir/*; do       ## Use ..* so you don't count the current dir (.) as hidden       if [[ $bn == .?* ]]; then        let hiddenDirectoryCounter+=1        listAllFiles $file       ## Match only the filename, not the whole path             elif [[ -f $file &&  $(basename $file) == .* ]]; then        let hiddenFileCounter+=1       elif [[ -f $file ]];then        let fileCounter+=1       elif [[ -d $file ]]; then        listAllFiles $file        let directoryCounter+=1       fi  done} listAllFiles $1echo File found: $fileCounterecho Directories found: $directoryCounterecho Hidden directories found: $hiddenDirectoryCounterecho Hidden files found: $hiddenFileCounterHowever, that is not a very good way of doing it, you can't deal with more than one directory as input, more importantly, you only check if $bn is a hidden directory, never $file which means you will never find more than one hidden directory and you are making it unnecessarily complicated. You could greatly simplify by using globstar. I would write this like so:#!/usr/bin/env bashshopt -s dotglob## globstar causes ** to match all files and directories## recursively.shopt -s globstar for dir in $@; do    for file in $dir/**; do      if [[ -f $file &&  $(basename $file) == .* ]]; then         let hiddenFileCounter+=1      elif [[ -d $file &&  $(basename $file) == .?* ]]; then         let hiddenDirectoryCounter+=1      elif [[ -f $file ]] ; then         let fileCounter+=1      elif [[ -d $file ]] ; then         let directoryCounter+=1      fi    donedoneecho Files found: $fileCounterecho Directories found: $directoryCounterecho Hidden directories found: $hiddenDirectoryCounterecho Hidden files found: $hiddenFileCounter