"find"를 사용하여 "rm"이 "-execdir"을 통해 실행될 때보다 더 완전한 경로 이름을 인쇄하도록 하려면 어떻게 해야 합니까?

"find"를 사용하여 "rm"이 "-execdir"을 통해 실행될 때보다 더 완전한 경로 이름을 인쇄하도록 하려면 어떻게 해야 합니까?

답변 요약: 문헌에서는 "-execdir"이 "-exec"보다 안전하다고 홍보하지만 작동상의 차이점을 무시하지 마십시오. 전자는 후자의 단순한 재구현이 아니다. 또한 대화형 삭제를 위해 특별히 find를 사용하는 경우 "-okdir" 옵션과 함께 "rm -f"를 실행하는 것도 가능합니다. 약간 더 복잡한 구조의 경우에도 마찬가지입니다.

"find" 명령을 배우려고 하는데 그 출력을 이해할 수 없습니다. 이것이 중복된다면 사과드립니다. 그러나 문제 설명은 약간 복잡하고 구글링하기 어렵습니다.

애완동물 상자를 설정하겠습니다. 일부 디렉터리(".")에서 시작하고 "A"와 "B"라는 두 개의 하위 디렉터리가 있습니다. 두 파일 모두 "hello.c"라는 파일이 있습니다.

예를 들어,

find . -name "hello.c"

다음과 같이 인쇄됩니다.

./A/hello.c
./B/hello.c 

여태까지는 그런대로 잘됐다. "-execdir" 옵션을 사용하려고 하면 길을 잃습니다. 대화형 삭제를 사용하고 싶다고 가정해 보겠습니다. 그 다음에:

find . -name "hello.c" -execdir rm -i {} \;

또는 유사합니다. 내가 기대했던 것은

rm: remove regular file "./A/hello.c"?

그런 다음 이 질문에 답하기 위해 유사한 "hello.c" 프롬프트가 "B" 디렉터리에 나타납니다. 불행하게도 실제로 일어나는 일은

rm: remove regular file "./hello.c"? 

이 작은 예에서는 "./A/hello.c"를 요청하고 있다고 합리적으로 추론할 수 있지만 이 예를 확장하면 경로 이름이 "./"로 잘린 수십 개의 파일을 얻게 됩니다. 수십 개의 "./hello.c"가 각각 어떤 하위 디렉터리에 있는지 구분할 수 없습니다.

그래서 내 질문은 "-execdir"을 통해 더 완전한 경로 이름을 인쇄하고 싶다는 것입니다. 맨페이지에서 내가 인지하지 못한 일부 미묘한 사항에 대한 힌트를 들을 수 있습니까? "{}" 교체에 ​​대해서는 알려진 바가 거의 없습니다. 또는 이 특정 사례를 관리하는 더 나은 방법(대화형 삭제)이 있다면 제 접근 방식이 모범 사례인지 확신할 수 없으므로 듣고 싶습니다.

답변1

GNU 매뉴얼 페이지에서는 find이에 대해 부분적으로 설명합니다.-execdir

와 유사 -exec하지만 지정된 명령은 일반적으로 시작한 디렉터리가 아닌 일치하는 파일이 포함된 하위 디렉터리에서 실행됩니다 find.

따라서 실제 미묘함은 포함되지 않습니다. -exec명령이 실행되는 디렉터리에서 명령을 호출하고 find(따라서 해당 디렉터리에 대한 상대 경로 또는 루트의 절대 경로를 제공해야 함) -execdir파일이 포함된 디렉터리에서 명령을 호출하므로 제공할 필요가 없습니다. 전체 경로 경로이므로 그렇지 않습니다.

원하는 동작을 얻으려면 -exec대신 를 사용해야 합니다 -execdir.

rm호출을 echo단순히 인수 목록(이 경우 파일 이름) 인쇄 로 대체하여 이 동작을 보여줄 수 있습니다 . 또는 -print외부 명령을 호출하지 않고 이를 수행하려면 which를 사용하십시오. (참고: -print지정되지 않은 경우 이는 기본 작업이기도 합니다.)

확인이 필요하지 않은 경우에 -delete작동합니다 . 이는 rm반복해서 호출하는 것을 방지하므로 많은 수의 파일에 대해 더 효율적일 수도 있습니다 .

답변2

보안상의 이점을 얻고 -execdir(실제로는 명령이 여러 구성 요소를 포함하는 경로를 가져오지 않도록 하기 위한 것임) 프롬프트를 얻으려면 다음을 사용할 수 있습니다.

find . -name hello.c -okdir rm -f {} \;

(적어도 GNU 구현은 GNU처럼 find터미널에 적합한 방식 rm(wrt 컨트롤, 줄 바꿈, 인쇄할 수 없는 문자...)으로 파일 이름을 이스케이프하지 않는다는 점에 유의하세요.)

답변3

-exec더 간단하지만 덜 안전한 디렉토리를 사용하는 대신 작업 디렉토리를 인쇄할 수 있습니다. 예를 들어

-execdir sh -c 'pwd ; rm -i "$1"' . {} \;

또는 전체 경로를 인쇄하십시오.

-execdir sh -c 'readlink -e "$1" ; rm -i "$1"' . {} \;

관련 정보