Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm trying to list all directories of a web server that are blocked by Apache via a .htaccess (containing deny from all). I've managed to get the list of blocking .htaccess but when I try to extract the directory path using dirname I have some errors:

  1. List of .htaccess files:

    find . -type f -name ".htaccess"
    ./.htaccess
    ./config/.htaccess
    ./files/.htaccess
    ./plugins/webservices/.htaccess
    ./plugins/webservices/scripts/.htaccess
    ./install/mysql/.htaccess
    ./scripts/.htaccess
    ./locales/.htaccess
    
  2. List of blocking .htaccess files:

    find . -type f -name ".htaccess" -exec sh -c "grep -Eli '^deny from all$' '{}'" \;
    ./config/.htaccess
    ./files/.htaccess
    ./plugins/webservices/scripts/.htaccess
    ./install/mysql/.htaccess
    ./scripts/.htaccess
    ./locales/.htaccess
    
  3. Error come the errors. Same list as in 2. but using xargs and dirname to get the containing directory:

    find . -type f -name ".htaccess" -exec sh -c "grep -Eli '^deny from all$' '{}' | xargs dirname" \;
    dirname: missing operand
    Try dirname --help' for more information
    ./config
    ./files
    dirname: missing operand
    Try dirname --help' for more information
    ./plugins/webservices/scripts
    ./install/mysql
    ./scripts
    ./locales
    
  4. Debug attempt of list 3: we can see 2 blank lines where the 2 errors were:

    find . -type f -name ".htaccess" -exec sh -c "grep -Eli '^deny from all$' '{}' | xargs echo" \;
    
    ./config/.htaccess
    ./files/.htaccess
    
    ./plugins/webservices/scripts/.htaccess
    ./install/mysql/.htaccess
    ./scripts/.htaccess
    ./locales/.htaccess
    

Theses 2 blank lines obviously matches the 2 .htaccess files that were ignore because they don't contains deny from all. I don't understand why I get these in lists 3. and 4. but not in 2.

share|improve this question
add comment

1 Answer 1

up vote 2 down vote accepted

It's failing because when the grep doesn't match, you're not passing anything to xargs.

For example:

  1. find gets ./.htaccess and calls your -exec.
  2. The grep doesn't match anything in the file, so it outputs nothing
  3. xargs launches dirname without any arguments, and so dirname thinks it was just misused and displays its help message.

The proper way to do this:

find . -type f -name .htaccess -exec grep -iq '^deny from all$' {} \; -printf '%h\n'
share|improve this answer
    
Thanks: works just fine and is simpler. I now do get why the blank lines: is there a way to skip/ignore them prior to calling xargs (not all cases can be resolved only via find :p)? –  CDuv May 23 at 10:28
1  
@CDuv --no-run-if-empty. However find is much safer. It will handle things that the grep/pipe method can't, such as filenames with newlines in them. –  Patrick May 23 at 12:25
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.