Apple Event: May 7th at 7 am PT

Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Bash 'find' bug

-

My Bash manual for 'Find' says:


'-depth Always true; same as the -d option.'


My experience is that -depth works but -d does not.


Is this a known issue?


If not can others confirm this behaviour?


-

Mac OS X (10.5.8), Two 733 MHz G4s with Leopard !

Posted on Apr 24, 2012 3:06 PM

Reply
20 replies

Apr 25, 2012 2:37 PM in response to BobHarris

Thanks for the explanation of how find works Bob.


I now understand the advantage of your method. It gives me exactly what I need, ie a list of folders and a false if none match.


The find man page says 'prune causes find to not descend into the current file' which gives no clue as to what it does in my case as I don't have a 'file' and it fails to define 'current'. Is there a better form of wording somewhere?

Apr 25, 2012 6:03 PM in response to Neville Hillyer

Also if the path fails to match I get an error at the terminal. Not very good for subsequent use in a plist as it will fill logs with silly messages.

You can kill error messages with


find /path/to/file/or/dir -prune ...other...stuff... >/dev/null 2>&1


which will cause all output and errors to disappear.


Is there a better form of wording somewhere

Unix man pages are notorious for minimum wording as written by the developer who often does not fully utilize all the features of the command, not like the users in general. If a man page has an example, you are lucky. Many times it is not what a man page say, it is what it doesn't say and reading between the lines.


And on 'find' is one of the much more complex and powerful commands that has had lots of different developers sticking their fingers into it many only understanding the small part they added because they wanted it, and not the other parts.


I've been using 'find' since '85 and except for simple searches, I have to read the man page, and then experiment, experiment, experiment to make sure I got the command right.


So no, I do not know of any better wording. I only know about experimentation and previous experience.


Not quite as good as I thought. I get a 'true' if the path matches even if subsequent criteria fail to match. I would have liked a true only if all conditions are fulfilled.

Is there a reason you need to know if the file/directory exists, but it does not match all the selection information? Did you want to do something to a file that does not match all the selectiion items? Would this be something that you could get 'find' to actually select if you included things like ! -xxxx which will invert the true/false value of the operator. Many of the numeric arguments can have + or - to select greater or less than the numeric value. If you get the selection operators to ignore files/directories you do not want to mess with, and only select files you need to do something with, would that be good enough?


There are other ways to do things you want. You can use a 'find' command to make a partial selection, and then use additional command to make a final decision


find "/path/to/file/or/directory" -xxxx -yyyy | while read file
do
    find "$file" -qqqq -rrrr -ssss | while read another
    do
        ...do something else... which could be any other Unix command
    done
done


There are a whole host of bash shell conditional that can be used against individual files


if [[ -d /path ]]; then
   echo this is a directory
fi

[[ -x /path ]] && echo this file has the executable bit set

[[ ! -s /path ]] && echo this file is empty

[[ /path1 -nt /path2 ]] && echo path1 is newer than path2

[[ /path1 -ef /path2 ]] && echo path1 and path2 are the same file even if the names are different


exactly what you are trying to do, and what things you need to test for would help others suggest solutions.

Apr 26, 2012 4:03 AM in response to BobHarris

Thanks again Bob. I am grateful for your helpful replies. I normally like to read the available information and experiment myself but in this case it appears that I am unlikely to discover the 'best' answer, particularly if 'find' is involved.


Leopard, and perhaps other OSs, have a frustrating habit of refusing to generate new folders on the desktop matching users' settings. As far as I am aware there are no settings or easy fixes for this except via third party software. Later OSs may be able to use a workaround via Automator. I am close to achieving a non-third party fix for this which matches my requirements.


I have researched the cause of the problem and as far as I can tell:


1 - Items without a .DS_Store file adopt view (and perhaps other) properties from their parent unless the property is defined by a user or global preference.


2 - This normally works well except for for folders first opened on the desktop. For example I dislike sidebars and can open new folders without them anywhere on my Mac except the desktop.


3 - A workaround can be automated with AppleScript.


4 - With osascript this can be combined with bash script and put in a plist file which watches ~/Desktop.


I have some experience of putting limited bash script in plist files and automating installation and load. This simplifies the process for both myself and non-technical users. I am aware that others may prefer to put the code in more conventional locations.


To run my existing bash/osa script I need indication and location from compact robust bash code when an "untitled folder*" is added to ~/Desktop. Since my script replaces the new folder I need to be particularly careful that I don't destroy anything. I am not too concerned about selecting more than one folder as long as they are empty and very recently created.


My script also opens the new folder and changes "untitled folder*" to a time stamp.

Apr 26, 2012 5:39 AM in response to Neville Hillyer

OK. Some suggestions


For "Untitled Folder" selection, use something like -Bmin -1 which will select any Untitled Folder found that is less than a minute old.


If you are worried about the folder being empty or almost empty (just has a .DS_Store), you could find new Untitled Folders, then do a sanity check on the inside. For example, the following bash (must be bash) code might do what you want:


TOTALLY_EMPTY_FOUND=0
EMPTY_WITH_DS_STORE_FOUND=0

while read name
do
    if [[ $(ls -a "${name}" | wc -l) -eq 2 ]]; then
        echo totally empty directory # put your special code here or call a function
        $((TOTALLY_EMPTY_FOUND++))
    fi

    if [[ $(ls -a "${name}" | wc -l) -eq 3 && -e "${name}/.DS_Store" ]]; then
        echo the directory ONLY has .DS_Store, but otherwise it is empty  # put your special code here or call a function
        $((EMPTY_WITH_DS_STORE_FOUND++))
    fi
done < <(find ~/Desktop/Untitled\ Folder* -prune -Bmin -1 >/dev/null 2>&1) # special bash trick

echo $TOTALLY_EMPTY_FOUND
echo $EMPTY_WITH_DS_STORE_FOUND


This would find empty or almost empty Untitled Folder's in the Desktop that were less than a minute old (that is the -Bmin -1 in action). It would not complain if it didn't find anything (the >/dev/null 2>&1 at work). It would allow you to do special processing when it found an empty folder or an empty folder with just a .DS_Store. It increments counters so that after the loop ends you can see if the loop found anything (this is where the speical bash < <(command) process redirection feature comes in which makes sure that while loop runs in the current shell context and the 'find' command runs in a sub-process (your typical "find | while" loop syntax puts the 'while' loop in a sub-process and any variables set in that sub-process are not seen by the current shell context, where as the "while ... do ... done < <(find)" notation keeps the "while" loop in the current shell context and all variables set are visible after the loop ends).


You can of course tailor this to your needs, assuming it even comes close to your needs.

Bash 'find' bug

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.