"find -exec"에서 "grep|xargs"를 실행할 때 빈 줄

"find -exec"에서 "grep|xargs"를 실행할 때 빈 줄

.htaccessApache를 포함하여 차단 deny from all된 웹 서버의 모든 디렉터리를 나열하려고 합니다. 차단 목록을 가져왔지만 다음을 .htaccess사용하여 디렉터리 경로를 추출하려고 하면 dirname몇 가지 오류가 발생합니다 .

  1. 파일 목록 .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. 차단된 파일 목록 .htaccess:

    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. 실수는 실수입니다. 2.와 동일한 목록이지만 포함된 디렉터리를 얻으려면 xargs및 를 사용하십시오.dirname

    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. 목록 3에 대한 디버깅 시도: 2개의 오류가 있는 2개의 빈 줄을 볼 수 있습니다.

    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
    

이 2개의 빈 줄은 .htaccess해당 파일이 포함되어 있지 않기 때문에 무시되는 2개의 파일과 분명히 일치합니다 deny from all. 목록 3과 4에서는 이러한 내용이 표시되지만 2에서는 표시되지 않는 이유를 이해할 수 없습니다.

답변1

grep이 일치하지 않을 때 xargs에 아무것도 전달하지 않기 때문에 실패합니다.

예를 들어:

  1. find을(를) 받아 ./.htaccess전화하세요 -exec.
  2. grep파일의 어떤 항목과도 ​​일치하지 않으므로 아무것도 출력되지 않습니다.
  3. xargsdirname매개 변수 없이 시작되었으므로 dirname남용되고 있다고 생각하고 도움말 메시지를 표시했습니다.

이를 수행하는 올바른 방법은 다음과 같습니다.

find . -type f -name .htaccess -exec grep -iq '^deny from all$' {} \; -printf '%h\n'

답변2

다음 오류가 발생했습니다.

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

dirname피연산자가 누락되었기 때문입니다 (아무것도 인수로 전달되지 않음). 이는 grep빈 결과가 반환되기 때문에 발생합니다 .

GNU를 사용하는 경우 ( )를 사용하여 입력이 비어 있을 때(공백이 아닌 항목이 포함되지 않음) 명령을 실행하지 않을 xargs수 있습니다 .-r--no-run-if-empty

BSD와 함께 작동하게 하려면 xargs명령을 다시 작성하여 입력이 비어 있는지 확인하고 그에 따라 명령을 실행해야 할 수도 있습니다. 또는 stderr를 억제하여 오류를 무시합니다. 예를 들면 다음과 같습니다.

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

또는 while 루프를 사용하여 빈 파일이나 파일 이름의 공백을 구문 분석할 때 발생하는 문제를 피할 수 있습니다.

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

관련 정보