첫 번째 일치 후 find 명령을 중지하는 방법은 무엇입니까?


131

find첫 번째 일치 항목을 찾은 후 명령 을 강제 로 중지 시키는 방법이 있습니까?


4
The Unseen : 헤드 -n 5로 파이프 될 때 5 개의 결과 후에 종료되는 이유는 5 개의 결과 후에 헤드가 종료되기 때문입니다. 헤드가 나갈 때 파이프가 닫히고 프로그램 파이프로 신호를 보내 파이프를 종료합니다. 답장을 보내지 않아 죄송합니다. 답장을 보내려면 50 개의 평판이 필요합니다.
Ruste

답변:


148

GNU 또는 FreeBSD find를 사용하면 다음 -quit조건자를 사용할 수 있습니다 .

find . ... -print -quit

NetBSD find와 동등한 기능 :

find . ... -print -exit

이름을 인쇄하고 파일 이름에 줄 바꿈 문자가 없다고 가정하면 다음을 수행 할 수 있습니다.

find . ... -print | head -n 1

그것은 find첫 번째 경기 이후에 멈추지 않을 것이지만, 아마도 두 번째 경기에서의 타이밍과 버퍼링 또는 (많은) 나중에에 따라 가능합니다. 기본적으로 findSIGPIPE head는 이미 첫 번째 입력 행을 읽고 표시했기 때문에 이미 사라진 동안 무언가를 출력하려고 시도하면 종료 됩니다.

모든 쉘이 해당 find명령 head이 리턴 된 후 대기하지는 않습니다 . ksh(비대화 yash식인 경우 ) 및 (파이프 라인이 스크립트의 마지막 명령 인 경우에만 ) Bourne 쉘 및 AT & T 구현은 백그라운드에서 실행되지 않습니다. 쉘에서 해당 동작을보고 싶다면 위의 내용을 항상 다음과 같이 변경할 수 있습니다.

(find . ... -print &) | head -n 1

찾은 파일의 경로를 인쇄하는 것 이상을 수행하는 경우 다음 방법을 시도해 볼 수 있습니다.

find . ... -exec sh -c 'printf "%s\n" "$1"; kill "$PPID"' sh {} \;

( printf해당 파일로 무엇을 하든지 대체 하십시오).

그것은 find종료 상태 를 반환하는 부작용 이 있지만 그것이 죽었다는 사실을 반영합니다.

실제로 SIGTERM 대신 SIGPIPE 신호를 사용하면 () kill -s PIPE대신 kill일부 쉘이 해당 죽음에 대해 더 침묵하게됩니다 (그러나 여전히 0이 아닌 종료 상태를 리턴 함).


3
누군가 파일이 술어와 일치하는지 테스트 해야하는 경우 Bash 및 GNU Find에서 파일을 발견하자마자 중지하고 다음을 수행 할 수 있습니다 if [[ $(find ... -print -quit) ]]; then ....
Tobia

@Tobia $(…)단일 괄호 ( [ … ]) 만 사용하는 경우 부품을 따옴표로 묶는 것이 좋습니다.
phk

@phk 단 괄호를 사용하지 않는다는 점을 제외하고는 (끔찍하기 때문에) 따옴표를 사용할 필요가 없습니다.
Tobia

2
@Tobia [는 표준 명령입니다. 끔찍한 명령은 아니지만 Bourne과 같은 쉘이 명령 줄을 구문 분석하는 방식입니다. [[...]]다양한 쉘에서 자체 문제가있는 ksh 구문입니다. 예를 들어 최근까지는 [[ $(...) ]]작동하지 않습니다 zsh(필요한 경우 [[ -n $(...) ]]). 를 제외하고 zsh, 당신이 따옴표를 필요 [[ $a = $b ]]는이 [[ =~ ]]구현 사이에도 일부에서 bash에 대한 버전 및 여러 버그와 호환되지 않는 차이가있다. 개인적으로 선호합니다 [.
Stéphane Chazelas

무엇 ...입니까? .
kyb

11
find . -name something -print -quit

인쇄 후 첫 번째 일치 후에 찾기를 종료합니다.

특정 양의 일치 후 찾기를 종료하고 결과를 인쇄하십시오.

find . -name something -print | head -n 5

놀랍게도 충분히-head는 이제 5 번 일치 한 후에 문자열을 종료하지만 어떻게 또는 왜하는지 모르겠습니다.

테스트하기가 매우 쉽습니다. 그냥하자 검색 찾을 적어도 분 이상을 복용하는 동안 수천, 어쩌면 더 많은 일치를 초래 루트. 그러나 "head"로 파이프 된 경우 "find"는 head에 정의 된 지정된 수의 라인 이후에 종료됩니다 (기본 헤드는 10을 표시하고 "head -n"을 사용하여 라인을 지정하십시오).

"head -n"이 지정된 줄 바꿈 문자 수에 도달하면 종료되므로 여러 줄 바꿈 문자가 포함 된 일치 항목도 그에 따라 계산됩니다.


나는 또한이 '프로그램이 헤드가 출력을 마친 후에 종료된다'는 현상을 관찰했지만 쉘 전체에서 일관되게 나타나지는 않았다. 나는 이것이 bash에 대한 자체 질문의 장점이라고 생각합니다. 다행히도 bash에 대한 대답은 이미 bash 스크립트를 사용한 StackOverflow의 Bash : Head & Tail 동작에 있습니다 . 그것은 프로그램이 백그라운드에서 종료되거나 계속 실행 될지 여부가 SIGPIPE에 대한 응답에 달려 있다는 결론을 내릴 수있는 충분한 정보를 제공합니다. 킬링이 기본값입니다.
Sage

나는 '프로그램 * / 쉘에서'를 의미했지만 분명히 unix.stackexchange.com은 첫 번째 주석을 편집하게하는 대신 두 번째 주석으로 기록하는 것을 선호합니다 (스택 교환, 사이트 별 정책 결정). 또한, @Ruste가 맨 위에이 효과에 대해 언급 한 것을 보았습니다.이 답변은 처음에 답을 찾은 후 처음에는 도움이되지 않았습니다 ...
sage

2

엔터테인먼트 목적으로 Bash의 게으른 찾기 생성기가 있습니다. 이 예제는 현재 디렉토리의 파일에 대한 링을 생성합니다. 그러나 당신이 원하는 많은 것을 읽으십시오 kill %+(아마도 1)

#!/usr/bin/env bash
unset -v files n
trap 'kill "$x_PID"' EXIT

coproc x while :; do
    find . -type f -maxdepth 1 -exec sh -c "$(</dev/fd/3)" _ {} +
done 4<&0 <<\EOF 3<&0 <&4-
for x; do
    read -r _
    printf '%s\0' "$x"
done
EOF

while
    echo >&${x[1]}
    IFS= read -rd '' -u "$x" 'files[n++]'
do
    printf '%q ' "${files[@]}"
    echo
    sleep .2
done

1

플래그와 함께 사용하는 경우 그렙 또한 반환 -m에 있으므로,

find stuff | grep -m1 .

find로 인쇄 된 첫 번째 줄 이후에 반환됩니다.

이것의 차이점 find stuff -print -quit | head -1은 검색이 빠르면 grep이 프로세스를 제 시간에 멈추지 못할 수도 있지만 (실제로 중요하지는 않지만) 검색이 길면 많은 것을 필요로하지 않는 인쇄를 찾을 수 없다는 것입니다 윤곽.

busybox grep도 -m실제로 필요하지 않기 때문에 이것은 busybox find와 함께 작동 합니다.

find /tmp/stuff -exec "sh" "-c" "eval 'echo {}; { kill \$PPID; }'" \;

이것은 (보통) sigterm 신호를 수신 한 찾기 프로세스에 대한 메시지를 뱉지 만,이 출력은 find 명령이 아닌 실행중인 쉘에 속하므로 명령 출력과 혼동되지 않으므로 파이프 또는 경로 재 지정은 단지 라인 만 출력합니다. 찾기와 일치합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.