1 2 Previous Next 20 Replies Latest reply: Apr 26, 2012 5:39 AM by BobHarris
Neville Hillyer Level 4 Level 4 (1,855 points)

-


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 !
  • 1. Re: Bash 'find' bug
    MrHoffman Level 6 Level 6 (12,455 points)

    Could be a bug, or it could be a command syntax error.  Please post the particular find command you are testing; the -d syntax is a slightly weird one, as it can be both an option, and a primary.  (With that command, somebody here can also test it against something newer than 10.5, too.)

     

    My preference on OS X is mdfind over find.  The mdfind command syntax is (yet) more cryptic (than find), but it's gonzo-fast; it's the command-line interface into Spotlight.

     

    And in general, bash command syntax does vary somewhat by platform, and by the version of the particular tool.   Use the man page to determine the particular syntax for the particular platform.  And there are the occasional bugs.

  • 2. Re: Bash 'find' bug
    BobHarris Level 6 Level 6 (13,090 points)

    I got identical results using

     

    /usr/bin/find -d path >tmp.1
    /usr/bin/find path -d >tmp.2
    /usr/bin/find path -depth >tmp.3
    

     

    And I got different results from the above using

     

    /usr/bin/find path >tmp.4
    
    cksum tmp.[1234]
    2923241020 29127374 tmp.1     # match
    2923241020 29127374 tmp.2     # match
    2923241020 29127374 tmp.3     # match
    618095947 29127374 tmp.4      # different
    

     

    So I cannot reproduce any errors.

     

    The above was a 10.7.3 system

     

    Using a 10.5.8 system

     

    cksum tmp.[1234]
    4233427378 28718 tmp.1     # match
    # the find path -d option was not valid; must be something newer than 10.5.8
    4233427378 28718 tmp.3     # match
    2987672313 28718 tmp.4     # different
    

     

    Message was edited by: BobHarris

  • 3. Re: Bash 'find' bug
    etresoft Level 7 Level 7 (24,265 points)

    find is not a bash builtin. It is a separate program.

     

    Also, which "-depth" are you looking at? There are two. "-depth n" limits the find to n directories deep. Both "-d" and "-depth" perform a depth-first traversal. The "-depth n" is a much more commonly used option. For what it's worth, "-d" and "-depth" do seem equivalent on my system.

  • 4. Re: Bash 'find' bug
    Neville Hillyer Level 4 Level 4 (1,855 points)

    .

    Thanks for the various replies.

     

    I came across my problem whilst doing something more complex but here is a simple demonstation:

     

     

    $ bash --version

    GNU bash, version 3.2.17(1)-release (powerpc-apple-darwin9.0)

     

    $ find /bin -depth -name bash

    /bin/bash

     

    $ find /bin -d -name bash

    find: -d: unknown option

    .

  • 5. Re: Bash 'find' bug
    BobHarris Level 6 Level 6 (13,090 points)

    The version of bash has nothing to do with the 'find' command.  They are 2 separate programs.

     

    "find /bin -d ..." syntax is not supported in the Mac OS X 10.5.8 'find' command.

     

    That syntax "IS" supported in 10.7.3

     

    In 10.5.8, you would need to use

     

    find -d /bin -name bash
    

    or

    find /bin -depth -name bash
    

     

    If staying on Mac OS X 10.5.8 is important, but you also need the "find /bin -d ..." syntax, you could most likely locate the open source 'find' copy and build a newer version for your system.  There are also packages such as MacPorts.org and Fink.sf.net which have Mac OS X ported open source packages available.

     

    Personally, I would just avoid the "find /bin -d ..." syntax, as there are valid work arounds.

  • 6. Re: Bash 'find' bug
    Neville Hillyer Level 4 Level 4 (1,855 points)

    Thanks Bob.

     

    Clearly inexperience in this area on my part. I don't recall previously coming across commands which have two position sensitive lists of options (albeit one called options and the other expressions / primaries / operands) before and after the path. Is this common? Having consulted the man page again I see that it is correct although I still find the definition: '-depth Always true; same as the -d option' misleading.

     

    My application does not allow me to upgrade my software. I am producing a means of creating new folders on standard Leopard desktops which comply with users' settings rather than inheriting them from the icon based desktop - a common source of annoyance resulting in several historic hacks, all of which (as far as I can tell) rely upon third party software - more on this later hopefully.

     

    Upon reflection it may be better for me to use -depth 1. I don't like 'find' as it always defaults to true, even if nothing is found, but I don't know what else to use to efficiently discover if a directory exists with a particular, name, size and date.

  • 7. Re: Bash 'find' bug
    BobHarris Level 6 Level 6 (13,090 points)

    Is this common?

    'find' is in a class all by itself.  But it is so useful and powerful, nothing has ever replaced it :-)

     

    If you need to look down a directory tree, then 'find' is the best first pass tool at finding files.

     

    Instead of -depth 0, you could use -prune

     

    if find /bin/bash -prune >/dev/null 2>&1; then
         echo /bin/bash exists
    fi
    

     

    The above form could also include other 'find' selection operators.

     

    If you know the directory, then you can also use

     

    if [[ -d /bin/bash ]]; then
        echo /bin/bash exists
    fi
    

     

    You can use ls -l to capture the time of a file and with different ls options you can choose the modification (default with -l), or the last accessed time (atime), or the last metadata mod time (aka ctime).  ls -l can also give you size.

     

    You can also use the 'stat' command to extract various file metadata information, such as time and size information.

  • 8. Re: Bash 'find' bug
    twtwtw Level 5 Level 5 (4,690 points)

    It's not entirely clear what your goal is (you havn't been specific), but if you're trying to find folders on the desktop that conform to particular naming conventions, here's a couple of alternate options to find that you can consider:

     

    use mdfind. (the following finds folders recursively on the desktop whose name begins with 'a'):

     

    mdfind "kMDItemContentType=='public.folder' && kMDItemFSName=='a*'" -onlyin ~/Desktop

     

    use applescript. (the following finds folders non-recursively on the desktop whose name begins with 'a'):

     

    tell application "System Events"

              set theFolders to every folder of desktop folder whose name begins with "a"

    end tell

  • 9. Re: Bash 'find' bug
    Neville Hillyer Level 4 Level 4 (1,855 points)

    Thanks for both replies.

     

    @ Bob

     

    So far I have got:

     

    $ find -d ~/Desktop -depth 1 -Bmin 1 -empty -iname "untitled folder*" -exec rm -d {} \;

     

    Depth needs to be set to 1. I am searching for directories, I assume this is why prune does not work. I need the -d to inhibit silly error messages unrelated to performance. I have yet to discover how to run the rest of my scripts when folders are found, a following && will not work as find always defaults to true. Perhaps I can put a function call in place of rm, I will try this later. It would be better to reduce Bmin to seconds but this does not look easy.

     

    I have used stat and grep before for files. It is not documented as working for directories but I see that it does. Perhaps not as concise as find for this application.

     

    @ twtwtw

     

    'mdfind' is not described as working for directories in my man page but it clearly does. Does it have the necessary selectors for size and date and depth?

     

    Where practical I prefer 'bash' rather than AppleScript, mainly for speed (launch and execution) but also script size. Having said that my script, which will be contained within a plist, already needs some AppleScript (via osascript) to open folders with the correct settings.

  • 10. Re: Bash 'find' bug
    twtwtw Level 5 Level 5 (4,690 points)

    mdfind has keys for size and date (kMDItemFSSize and kMDItemFSCreationDate or kMDItemFSContentChangeDate - I don't know if they are the 'necessary' ones since you haven't told us what you're doing).  You can't specify a particular depth, so far as I know; mdfind always searches the entire hierarchy starting at the folder you specify.  you'd have to filter the results if you only wanted it to go to a specific depth.  see the query programming syntax and metadata attributes references.

     

    As far as applescript goes - frankly - sometimes it's just easier to do stuff in applescript than in the shell.

  • 11. Re: Bash 'find' bug
    BobHarris Level 6 Level 6 (13,090 points)
    find ~/Desktop/untitled\ folder* -prune  -Bmin 1 -empty -exec rmdir {} \;
    

     

    This works for me.

  • 12. Re: Bash 'find' bug
    Neville Hillyer Level 4 Level 4 (1,855 points)

    Thanks for the interesting mdfind links - looks very flexible. I only want to search one directory so I could use '-onlyin dir'. Pity my mdfind man gave no clue about the flexibility. This is all it says:

     

    mdfind(1)                 BSD General Commands Manual                mdfind(1)
    
    NAME
         mdfind -- finds files matching a given query
    
    SYNOPSIS
         mdfind [-live] [-count] [-onlyin directory] query
    
    DESCRIPTION
         The mdfind command consults the central metadata store and returns a list
         of files that match the given metadata query. The query can be a string
         or a query expression.
    
         The following options are available:
    
         -0          Prints an ASCII NUL character after each result path.  This
                     is useful when used in conjunction with xargs -0.
    
         -live       Causes the mdfind command to provide live-updates to the num-
                     ber of files matching the query.  When an update causes the
                     query results to change the number of matches is updated.
                     The find can be cancelled by typing ctrl-C.
    
         -count      Causes the mdfind command to output the total number of
                     matches, instead of the path to the matching items.
    
         -onlyin dir
                     Limit the scope of the search to the directory specified.
    
         -literal    Force the provided query string to be taken as a literal
                     query string, without interpretation.
    
         -interpret  Force the provided query string to be interpreted as if the
                     user had typed the string into the Spotlight menu.  For exam-
                     ple, the string "search" would produce the following query
                     string:
                           (* = search* cdw || kMDItemTextContent = search* cdw)
    
    EXAMPLES
         The following examples are shown as given to the shell.
    
         This returns all files with any metadata attribute value matching the
         string "image":
    
               mdfind image
    
         This returns all files that contain "MyFavoriteAuthor" in the kMDItemAu-
         thor metadata attribute:
    
               mdfind "kMDItemAuthor == '*MyFavoriteAuthor*'"
    
         This returns all files with any metadata attribute value matching the
         string "skateboard".  The find continues to run after gathering the ini-
         tial results, providing a count of the number of files that match the
         query.
    
               mdfind -live skateboard
    
         To get a list of the available attributes for use in constructing
         queries, see mdimport(1), particularly the -X switch.
    
    SEE ALSO
         mdimport(1), mdls(1), mdutil(1), xargs(1)
    
    Mac OS X                         June 10, 2004                        Mac OS X
    
    (END) 
    
    
  • 13. Re: Bash 'find' bug
    Neville Hillyer Level 4 Level 4 (1,855 points)

    Thanks Bob.

     

    I can only think that I did a silly test such as:

     

    find ~/Desktop -depth -name "untitled folder*" -prune

     

    As documented this should work although I should have been more circumspect as I was aware of the warning at the end of the following:

     

    -prune  This primary always evaluates to true.  It causes find to no

                 descend into the current file. Note, the -prune primary has no

                 effect if the -d option was specified.

     

    I do wish the man was more accurate. It gave no warning of the incompatibility with the -depth primary. Also it did not mention not descending into the specified directory. I note that often 'file' means files or directories but on other occasions it does not. There appears to be no clues about how specific it is intended to be.

  • 14. Re: Bash 'find' bug
    Neville Hillyer Level 4 Level 4 (1,855 points)

    I spoke too soon Bob.

     

    This works:    find ~/Desktop -name folder -prune

     

    but this does not:    find ~/Desktop -prune -name folder

     

    Do you know why? As far as I can tell from the man page they should both work.

1 2 Previous Next