Bash – Exit bash when find gets to a folder with permission denied

bashdirectoryfindpermissionsshell-script

I'm trying to write a Bash script. Where I go through folders recursively and make a list of and count files and folders.

In a way it works but if "find" gets to a directory where it has permission denied it just continues the script. Skipping the directory not counting files in it nor telling me the directory is permission denied.
(other than a useless terminal command which I can't use since the scripts is run through file-manager custom actions)

I would like it to when "find" finds a permission denied folder to stop the searching process and report to me what folder has permission denied. So I know what its skipping and why.

Half my code looks like this

#!/bin/bash

allfolders=("$@")
nfolders="0"

Nfilesinfolders="0"
filesinfolder="0"

results=""
noteadded="0"

for directory in "${allfolders[@]}"; do

    echo "This is where I try and insert the code examples below.
    echo "and want it to exit with a zenity error"

    nfolders=$(( nfolders + 1 ))
    echo "$nfolders"

if [[ $nfolders -ge 11 ]]
    then
      if [[ $noteadded -ge 0 ]]
        then
          results+="\n"
          results+="Not adding any more folders to the list. Look at the top for total number of files"
          noteadded=1
      fi
 else
     results+="$directory\n"
 fi

 echo "This below attempt only worked on the top folder not folders in it"

 if [[ -r "$directory" ]] && [[ -w "$directory" ]]
     then
         filesinfolder=$(find "$directory" -depth -type f -printf '.' | wc -c)
         Nfilesinfolders=$(( Nfilesinfolders + filesinfolder ))
     else
         zenity --error --title="Error occured check message" --text="The directory\n $directory\n is not readable or write-able to you $USER\n please run as root"
         exit $?
    fi
done

Here are then some of my failed attempts

find "$directory" -depth -type d -print0 | while IFS= read -r -d $'\0' currentdir
do
    echo "Checking "$currentdir" in directory "$directory""
    if [[ ! -r "$currentdir" ]] && [[ ! -w "$currentdir" ]]
        then
            zenity --error --title="Error occurred check message" --text="The directory\n $currentdir\n is not readable or write-able to you $USER\n please run as root"
            exit $?
fi
   done

The above code seems like its just getting skipped and continues on the script.

The next one looked like this. I could get it to report an error but not tell me what folder that went wrong.

shredout=$(find "$directory" -depth -type d -print0 2>&1 | grep "Permission denied" && echo "found Permission Denied" && checkfolderperm="1" )

if [[ $checkfolderperm -eq 1 ]] 
    then
        zenity --error --title="Error occurred check message" --text="The directory\n $directory\n is not readable or write-able to you $USER\n please run as root"
        exit $?
fi

But the above also seems like its just getting skipped.

the last one is all-most like my first try.

while IFS= read -r -d $'\0' currentdir; do
    echo "going through file = $currentdir in folder $directory"
    if [[ ! -r "$currentdir" ]] && [[ ! -w "$currentdir" ]]
        then
        zenity --error --title="Error occured check message" --text="The directory\n $currentdir\n is not readable or write-able to you $USER\n please run as root"
        exit $?
    fi
done < <(find "$directory" -depth -type d -print0)

but that also gets skipped.

Is there any way for me to go through folders with find. Then stop and report if a directory is permission denied.

I've come across bash "traps" and bash "functions" but can't figure out if they are my solution or how to use them.


This is the resulting code after help from "meuh".
It stops the script and reports exactly what folder/folder's it doesn't have permission to. Hope it can help others like it did me.

if finderrors=$(! find "$directory" -depth -type d 2>&1 1>/dev/null)
    then 
        zenity --error --title="Error occurred check message" --text="$finderrors"
        exit $?
fi

Best Answer

find will set its return code to non-zero if it saw an error. So you can do:

if ! find ... 
then    echo had an error >&2
fi |
while ...

(I'm not sure what you want to do with the find output).


To collect all the error messages from find on stderr (file descriptor 2) you can redirect 2 to a file. Eg:

if ! find ... 2>/tmp/errors
then     zenity --error --text "$(</tmp/errors)"
fi |
while ...
Related Question