Linhas em branco ao executar “grep | xargs ”em um“ find -exec ”

5

Estou tentando listar todos os diretórios de um servidor da Web que são bloqueados pelo Apache por meio de .htaccess (contendo deny from all ). Eu consegui pegar a lista de bloqueio .htaccess mas quando tento extrair o caminho do diretório usando dirname eu tenho alguns erros:

  1. Lista de arquivos .htaccess :

    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. Lista de arquivos .htaccess de bloqueio:

    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. Erro nos erros. Mesma lista que em 2. mas usando xargs e dirname para obter o diretório que contém:

    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. Tentativa de depuração da lista 3: podemos ver duas linhas em branco em que os dois erros foram:

    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
    

Teses 2 linhas em branco correspondem obviamente aos arquivos de 2 .htaccess que foram ignorados porque não contêm deny from all . Eu não entendo porque eu as coloco nas listas 3. e 4. mas não em 2.

    
por CDuv 22.05.2014 / 23:37

2 respostas

2

Está falhando porque quando o grep não combina, você não está transmitindo nada para xargs.

Por exemplo:

  1. find obtém ./.htaccess e chama seu -exec .
  2. O grep não corresponde a nada no arquivo, por isso não produz nada
  3. xargs lança dirname sem nenhum argumento e, portanto, dirname acha que foi apenas usado incorretamente e exibe sua mensagem de ajuda.

A maneira correta de fazer isso:

find . -type f -name .htaccess -exec grep -iq '^deny from all$' {} \; -printf '%h\n'
    
por 22.05.2014 / 23:57
0

Você tem esse erro:

dirname: missing operand. Try dirname --help' for more information

porque dirname está em falta (nada foi passado como argumento). Isso aconteceu porque grep retornou resultados vazios.

Se você estiver usando o GNU xargs , você pode usar -r ( --no-run-if-empty ) para não executar o comando, quando a entrada estiver vazia (não contém nenhum não-blanks).

Para fazê-lo funcionar com o BSD xargs , você provavelmente precisará reescrever seu comando para verificar se a entrada está vazia e executar o comando de acordo. Ou simplesmente ignore o erro suprimindo stderr, por exemplo:

find . ... -exec sh -c "grep ... | xargs dirname 2> /dev/null || true" ';'

Ou você pode usar o loop while para evitar a análise de arquivos vazios ou problemas com espaços em nomes de arquivos, por exemplo,

find . -type f -name ".htaccess" -print0 | while IFS= read -r -d '' file; do

    grep -Eli '^deny from all$' "$file" | while IFS= read -r -d '' deny_file; do
      dirname "$deny_file"
    done

done
    
por 14.05.2016 / 00:23