Results 1 to 1 of 1

Thread: GNU find: Suppress "Permission denied" + Script [SOLUTION]

  1. #1
    Join Date
    Oct 2006
    Beans
    24
    Distro
    Ubuntu 9.10 Karmic Koala

    Lightbulb GNU find: Suppress "Permission denied" + Script [SOLUTION]

    I came up with a way to quell the plenitude of "Permission denied" lines I constantly get which only clog up my results from a find command. It's not something I want to type all the time, to be sure, and it will only work for Bourne family shells (and I'm fond of tcsh for interacting) so I put it in a script. I call it qfind. Please do understand how it's put together. There's no warranty!

    Code:
    #!/bin/sh
    # qfind 
    # usage: just like find, but quells the bull. 
    #        see 'man find'
    #
    
    /usr/bin/find $@ 2>&1 | grep -ve '^/usr/bin/find: .*: Permission denied$'
    
    #^^^^^^^ full path here  ...       ^^^^^^^ or this won't match!
    Explanation:
    This calls find with all the arguments passed along in $@ . Then stderr is redirected to stdout with the construct 2>&1 ... Then it's all piped to grep which is given the -v (invert) switch to return all lines NOT matching, and the -e switch to specify that a regular expression follows.

    The regular expression (regex) is: ^/usr/bin/find: .*: Permission denied$

    ^ = matches the beginning of the line
    /usr/bin/find: = literal text including trailing colon, space -- This is matched by an explicit call to /usr/bin/find, but not just find !!
    .* = matches any character, zero times or more; whatever you don't have permissions for is matched by this.
    : Permission denied = literal text. Again, the colon and space are part of the literal pattern to oppress; they are not special.
    $ = matches the end of the line.

    Beware the special case: I suppose it could be possible for legitimate find results to be filtered out. This is the primary reason for using the full path /usr/bin/find because it will show up in the error output (along with the trailing colon and space), and be searched for to filter out. This makes it hella unlikely that a false hit would really happen. But it's not technically impossible. And I know it's a little inelegant overall, but until there's a find option like --screw-permissions, this will work just dandy for me. :o)

    Why Bother:
    Surely I have not scoured the ENTIRE internet, but nowhere have I found this solution. I have found lots of redirecting all stderr to the /dev/null device. Of course then you get no error messages at all. This here crafty workaround though, allows other errors to show up. With find particularly, I'm prone to incite other errors at a frightening clip, so I want to know about them. Meanwhile when I do figure out what I'm doing, the results are useful because they contain only my results.

    I hope that someone out there is clever enough to come up with an elegant way to redirect the stderr separate from stdout altogether. I'm surprised not to have found anything of the sort. That would be very useful in general, no? If anyone can show me a way to do that (or even how to do this in csh / tcsh) then please share! This works for my case though, so I'm putting it somewhere google can find it. :o)

    Edify yourself further: regex . redirection

    Enjoy!


    ------------

    In case you're interested, it was laziness that got me started on this:
    Code:
    #!/bin/sh
    # wheresmy
    # usage: wheresmy term [term2] [term3]
    #
    
    FILTER_OUT="^/usr/bin/find: .*: Permission denied$"
    
    /usr/bin/find /media1 -iname '*'$1'*'$2'*'$3'*' 2>&1| grep -ve "$FILTER_OUT"
    /usr/bin/find /media2 -iname '*'$1'*'$2'*'$3'*' 2>&1| grep -ve "$FILTER_OUT"

    This way, I can be lazy, er, I mean ... I can find my media files quickly and effectively!
    For example, I want to know the path to Nodame Cantabile, episode 3, but alas, I can't spell at all. I just type in a good guess:

    wheresmy nod cant 03

    and i quickly get my result:

    /media2/anime/Nodame Cantabile/Nodame_Cantabile_-_03.mkv

    If only one term is specified, it's inelegant, but still works just fine. The * wildcards simply pile up like this: *oneterm*** which probably wastes some CPU cycles, but has no effect on the output.

    Now to find my keys ...

    -- Nate
    Last edited by natrik; November 25th, 2008 at 02:05 PM. Reason: oops ... typo.

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •