3

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

1 Answer 1

8

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 ...
5
  • It solved halve my puzzle thank you. Now i can make it show zenity and exit if an error occur. Now the other problem im still having is it only reports the main directory etc. "find /etc/test1 -depth -type d". It only reports an error in "/etc/test1" I would like it to report the actual folder with permission denied. "/etc/test1/permissiondenied" folder. Is that possible to ?
    – Darkyere
    Commented Aug 26, 2015 at 10:34
  • I added to my answer how to collect the error messages.
    – meuh
    Commented Aug 26, 2015 at 10:54
  • Ty for the answer i just noticed. I will try this and see if i can add the error to a string or array instead to work with. If thats even possible. Right now ive just had a friend pop in the doors so ill have to wait to try for now. Thank you by the way for answering me so far it got me further than ive been before.
    – Darkyere
    Commented Aug 26, 2015 at 11:26
  • Ty so much for you assistance. By your help i can now make it stop and report exactly which folder has permission denied. I will add the very smal code to the bottom of my post at the top. For other people to find yousefull or comment about :) Ty and best regards
    – Darkyere
    Commented Aug 26, 2015 at 14:58
  • You could "set -e" ... but be mindful of its side effects... Commented Jan 6, 2016 at 9:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .