[bash] “find”에서“permission denied”메시지를 모두 제외하려면 어떻게해야합니까?

다음 에서 권한 거부 메시지를 모두 숨겨야합니다 .

find . > files_and_folders

그런 메시지가 나올 때 실험 중입니다. 발생하지 않는 모든 폴더와 파일을 수집해야합니다.

권한 수준을 files_and_folders파일로 지정할 수 있습니까?

동시에 오류를 숨기려면 어떻게해야합니까?



답변

참고 :
*이 답변은 사용 사례보다 더 깊어 find 2>/dev/null질 수 있으며 많은 상황에서 충분할 수 있습니다. 크로스 플랫폼 관점과 가능한 한 강력한 솔루션을 찾는 데 관심이있는 일부 고급 쉘 기술에 대한 논의에 여전히 관심이있을 수 있습니다.
* 시스템이 현지화 된 오류 메시지 를 표시하도록 구성된 경우 영어 메시지가보고 되도록 find아래 의 호출 앞에 LC_ALL=C( LC_ALL=C find ...)를 붙이면 의도 한대로 작동합니다. 변함없이, 그러나, 오류 메시지 않습니다 표시 얻을는 영어로도됩니다. grep -v 'Permission denied'

귀하의 경우 쉘이 bashzsh , 거기에 합리적으로 간단하면서 강력 솔루션 사용, 단지 POSIX 호환 find기능 ; 반면 bashPOSIX의 일부가 아닌 자체, 가장 현대적인 유닉스 플랫폼은이 솔루션이 널리 휴대하고, 그와 함께 :

find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)

참고 : 전체 명령이 내부 명령이 완료 grep될 때까지 기다리지 않기 때문에 일부 출력이 완료된 도착할 가능성이 적습니다 . 에서가 , 당신은 추가하여이 문제를 방지 할 수 있습니다 명령에.find>(...)bash| cat

  • >(...)A (거의 사용하지 않음)입니다 출력 프로세스 대체 (이 경우 출력을 리디렉션 허용, 표준 에러의 출력 ( 2>명령 내부의 표준 입력으로) >(...).
    에 추가 bash하고 zsh, ksh뿐만 아니라 지원을 원칙으로 하지만,에서 리디렉션을 결합하는 시도 여기에서 수행 된 stderr ( 2> >(...)) 은 자동으로 무시되는 것으로 보입니다 ( ksh 93u+).

    • grep -v 'Permission denied'구문을 포함하는 모든 명령 행 ( 명령의 stderr 스트림에서)을 필터링 하고 ( -v) 나머지 행을 stderr ( ) 로 출력합니다 .findPermission denied>&2

이 접근법은 다음과 같습니다.

  • strong : 오류 메시지grep 에만 적용되며 (파일 경로와 오류 메시지의 조합으로 인해 오 탐지로 이어질 수 있음) 권한이 거부 된 오류 이외의 오류 메시지는 stderr로 전달됩니다.

  • side-effect free : find의 종료 코드가 유지됩니다. 발생한 파일 시스템 항목 중 하나 이상에 액세스 할 수 없으면 종료 코드 가 발생합니다 (권한이 거부 된 1오류 이외의 오류가 발생했는지 여부는 알려지지 않음 ).


POSIX 호환 솔루션 :

완전히 POSIX 호환 솔루션에는 제한이 있거나 추가 작업이 필요합니다.

경우 find의 출력이 포착 될 파일 어쨌든 (또는 전부 억제), 다음에서 파이프 라인 기반 솔루션 조나단 레플러의 대답은 간단하고, 강력하고, POSIX 호환은 다음과 같습니다

find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2

다음 리디렉션 문제의 순서가 있습니다 2>&1와야 첫째 .

파일 앞쪽에 stdout 출력을 캡처 하면 파이프 라인을 통해 오류 메시지 2>&1 보낼 수 있으며 ,이 메시지 는 명확하게 작동 할 수 있습니다.grep

유일한 단점이다 전반적인 종료 코드가 될 것입니다 grep명령의 하지 find가없는 경우 :이 경우 수단에의, 아니 모든 또는 오류 허락-거부 오류, 종료 코드가 될 것이다 1(신호 실패 (그렇지 않으면) 권한 거부 오류 이외의 오류) 0-의도의 반대입니다.
그러나 find‘종료 코드는 존재하지 않는 경로를 전달하는 것과 같은 근본적인 실패를 넘어 정보를 거의 전달하지 않기 때문에 어쨌든 거의 사용되지 않습니다 .
그러나 일부 의 경우에만입력 경로에 의한 권한의 부족으로 액세스가되는 됩니다 에 반영 find(GNU와 BSD 모두의 종료 코드 find) : 사용 권한 – 거부 오류가 발생하면 모든 처리 된 파일의 종료 코드로 설정됩니다 1.

다음과 같은 변형이 다음을 해결합니다.

find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }

이제 종료 코드는 다른 오류 Permission denied 발생 했는지 여부를 나타냅니다 ( 1그렇다면 0그렇지 않은 경우).
즉 : 성공 (: 종료 코드는 이제 명령의 진정한 의도를 반영하는 0) 모든 또는 오류 경우,보고 있는 권한 – 거부 오류가 발생하지합니다.
이것은 find상단의 솔루션에서와 같이 종료 코드를 전달하는 것보다 훨씬 낫습니다 .


gniourf_gniourf 코멘트에은 (여전히 POSIX 호환) 제안 정교한 리디렉션을 사용하여이 솔루션의 일반화 , 에 파일 경로 인쇄의 기본 동작으로도 작동 표준 출력 :

{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1

한마디로 : 사용자 정의 파일 디스크립터 3는 stdout ( 1)과 stderr ( 2) 를 임시로 교환하는 데 사용 되므로 오류 메시지 grep stdout 을 통해 파이프 될 수 있습니다 .

이러한 경로 재 지정이 없으면 데이터 (파일 경로) 오류 메시지가 모두 grepstdout 을 통해 파이프되고 오류 메시지이름 이 문구 를 포함 하는 (가설) 파일grep 을 구별 할 수 없습니다 . Permission deniedPermission denied

최초의 솔루션과 마찬가지로, 그러나, 종료 코드가 될 것보고 grep의하지 find적용 할 수 있습니다 위와 같이의,하지만 같은 수정.


기존 답변에 대한 참고 사항 :

  • 에 대해 유의해야 할 몇 가지 포인트가 있습니다 마이클 Brux의 대답은 , find . ! -readable -prune -o -print:

    • GNU 가 필요합니다 find. 특히 macOS에서는 작동하지 않습니다. 물론, GNU와 함께 작동하는 명령 만 필요한 경우 find에는 문제가되지 않습니다.

    • 일부 Permission denied오류는 여전히 나타날 수 있습니다 . 현재 사용자에게는 권한이 있지만 실행 가능한 권한 이없는 디렉토리 find ! -readable -prune하위 항목에 대한 오류를보고합니다 . 그 이유는 디렉토리 자체 읽을 수 있고 실행되지 않기 때문에 해당 디렉토리 로 내려 가려고 하면 오류 메시지가 트리거 되기 때문입니다. 즉, 일반적인 경우는 권한이 누락 된 것입니다.rx-pruner

    • 참고 : 다음 사항은 철학 및 / 또는 특정 유스 케이스의 문제이며, 사용자와 관련이 없으며 특히 경로 를 인쇄 하는 것이 모든 경우 명령이 사용자의 요구에 적합하다고 결정할 수 있습니다 .

      • 권한 거부 오류 메시지의 필터링 을 임의의 명령 에 적용 할 별도의 작업으로 개념화하는 경우 권한 거부 오류 를 사전에 방지 하는 반대의 접근 방식 에서는 명령에 “노이즈”를 도입해야합니다. 복잡성과 논리적 함정 . findfind
      • 예를 들어 Michael의 답변에 대해 가장 많이 언급 된 의견 (이 글을 쓰는 시점) 은 다음과 같이 필터 를 포함하여 명령 을 확장 하는 방법을 보여 주려고합니다 -name.
        find . ! -readable -prune -o -name '*.txt'
        그러나 후행 작업이 필요 하므로 의도 한대로 작동 하지 않습니다. ( 이 답변 에서 설명을 찾을 수 있습니다 ). 이러한 미묘함은 버그를 유발할 수 있습니다.-print
  • 첫 번째 솔루션 조나단 레플러의 대답은 , find . 2>/dev/null > files_and_folders그 자신이 상태로, 맹목적으로 침묵 모든 오류 메시지를 (그리고 그는 또한 설명으로 해결 방법은 완전히 강력한 가시고하지 않습니다). 그러나 실용적으로 말하자면 모든 오류가 권한과 관련이 있다고 가정하는 것이 가장 간단한 해결책 입니다.

  • 안개의 대답은 , sudo find . > files_and_folders, 간결하고 실용적인,하지만 단지 이외의 아무것도 경솔한입니다 인쇄 파일 이름 보안상의 이유로 : 당신이로 실행하고 있기 때문에 루트 사용자, “당신은 발견 버그로 엉망이되고 전체 시스템을 위험을 감수 또는 악의적 인 버전, 또는 정상적인 권한으로이 작업을 실행 한 경우 (에 의해 안개의 대답에 코멘트에서 “일어날 수없는 예기치 않게 뭔가를 기록 잘못된 호출, tripleee ).

  • 에서 제 2 회 솔루션 viraptor의 대답은 , find . 2>&1 | grep -v 'Permission denied' > some_file그리고 잠재적으로 대신보고 (때문에 파이프 라인을 통해 표준 출력과 표준 에러의 혼합을 보내기) 잘못된 반응의 위험을 실행 출력 경로와 함께 캡처, 그들에게 열려진 통해 -permission-거부 오류 출력 파일에.


답변

사용하다:

find . 2>/dev/null > files_and_folders

이것은 Permission denied물론 오류뿐만 아니라 모든 오류 메시지를 숨 깁니다 .

심볼릭 링크에 너무 많은 홉과 같은 다른 가능한 오류를 유지하고 싶지만 권한이 거부 된 것이 아니라면 ‘permission denied’라는 파일이 많지 않다는 추측을해야합니다. 시도해보십시오 :

find . 2>&1 | grep -v 'Permission denied' > files_and_folders

표준 오류 만 엄격하게 필터링하려면보다 정교한 구성을 사용할 수 있습니다.

find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2

find명령 의 I / O 리디렉션 은 다음과 같습니다 2>&1 > files_and_folders |.. 파이프는 표준 출력을 grep명령으로 리디렉션 하고 먼저 적용됩니다. 은 2>&1표준 출력 (파이프)와 같은 장소에 표준 오차를 보낸다. 는 > files_and_folders파일에 표준 출력 (그러나 표준없는 오류)을 보냅니다. 결과적으로 표준 오류에 기록 된 메시지가 파이프로 전송되고 일반 출력 find이 파일에 기록됩니다. 는 grep표준 출력이 최종 (당신은 당신이 원하는 선택, 및 로케일 및 O / S에 따라 철자를 변경해야 할 수 있습니다 방법을 결정할 수 있습니다) 필터>&2생존 오류 메시지 (표준 출력에 기록됨)가 표준 오류로 한 번 더 이동 함을 의미합니다. 최종 리디렉션은 터미널에서 선택 사항으로 간주 될 수 있지만 표준 오류에 오류 메시지가 표시되도록 스크립트에서 사용하는 것이 좋습니다.

수행하려는 작업에 따라이 테마에는 끝없는 변형이 있습니다. 이것은 Bourne 쉘 파생물 (Bash, Korn,…) 및 POSIX 호환 버전의 모든 Unix 변형에서 작동합니다 find.

find시스템에 있는 특정 버전에 적응하려면 대체 옵션을 사용할 수 있습니다. find특히 GNU 에는 다른 버전에서는 사용할 수없는 수많은 옵션이 있습니다. 이러한 옵션 중 하나에 대해서는 현재 허용되는 답변을 참조하십시오.


답변

사용하다:

find . ! -readable -prune -o -print

또는 더 일반적으로

find <paths> ! -readable -prune -o <other conditions like -name> -print
  • “권한 거부”를 피하기 위해
  • AND (기타) 오류 메시지를 표시하지 마십시오
  • 종료 상태 0을 얻습니다 ( “모든 파일이 성공적으로 처리되었습니다”).

작동 : find (GNU findutils) 4.4.2. 배경:

  • -readable테스트 읽을 파일을 일치합니다. !테스트가 false 인 경우 연산자는, true를 돌려줍니다. ! -readable읽을 수없는 디렉토리 (& 파일) 와 일치합니다.
  • -prune조치는 디렉토리로 내려하지 않습니다.
  • ! -readable -prune 디렉토리를 읽을 수없는 경우 디렉토리로 내려 가지 마십시오.
  • -readable테스트 계정 액세스 제어 목록과 다른 권한 유물에 걸리는 -perm테스트 무시합니다.

자세한 내용은 find(1) 맨 페이지 를 참조하십시오.


답변

루트 “/”에서 검색을 시작하려면 다음과 같은 출력이 표시 될 것입니다.

find: /./proc/1731/fdinfo: Permission denied
find: /./proc/2032/task/2032/fd: Permission denied

허가 때문입니다. 이 문제를 해결하려면

  1. sudo 명령을 사용할 수 있습니다 :

    sudo find /. -name 'toBeSearched.file'

슈퍼 사용자의 암호를 묻습니다. 암호를 입력하면 원하는 결과가 표시됩니다. sudo 명령을 사용할 수있는 권한이없는 경우 수퍼 유저 암호가없는 경우 먼저 시스템 관리자에게 sudoers 파일에 추가하도록 요청하십시오.

  1. (일반적으로 디스플레이 / 스크린)의 표준 오류 출력을 일부 파일로 리디렉션하고 화면에 오류 메시지가 표시되지 않도록 할 수 있습니다! 특수 파일 / dev / null로 리디렉션하십시오.

    find /. -name 'toBeSearched.file' 2>/dev/null
  2. 표준 오류 출력을 (일반적으로 표시 / 화면)에서 표준 출력 (일반적으로 표시 / 화면)으로 재 지정한 다음 grep 명령을 -v “invert”매개 변수와 함께 파이프하여 ‘Permission denied’가있는 출력 행을 표시하지 않을 수 있습니다. 단어 쌍 :

    find /. -name 'toBeSearched.file' 2>&1 | grep -v 'Permission denied'

답변

나는 사용해야했다 :

find / -name expect 2>/dev/null

찾고자하는 이름을 지정한 다음 모든 오류를 / dev / null로 리디렉션하도록 지시합니다.

내가 찾던 기대 프로그램의 위치가 될 것으로 기대하십시오.


답변

파이프 stderr/dev/null사용하여 2>을 / dev / null을

find . -name '...' 2>/dev/null


답변

당신은 또한 사용할 수 있습니다 -perm-prune(참조 읽을 디렉토리로 내려 피하기 위해 조건을 ? 내가 찾기 프로그램에서 출력 문 “권한이 거부”를 제거하려면 어떻게 – 유닉스 및 리눅스 스택 교환 ) :

find . -type d ! -perm -g+r,u+r,o+r -prune -o -print > files_and_folders