찾기에서 exec와 함께 세미콜론 (;) 대 더하기 (+) 사용


159

사용시 출력에 차이가있는 이유

find . -exec ls '{}' \+

find . -exec ls '{}' \;

나는 얻었다 :

$ find . -exec ls  \{\} \+
./file1  ./file2

.:
file1  file2  testdir1

./testdir1:
testdir2

./testdir1/testdir2:


$ find . -exec ls  \{\} \;
file1  file2  testdir1
testdir2
./file2
./file1

답변:


249

이것은 예제와 함께 가장 잘 설명 될 수 있습니다. 다음 find과 같은 파일 이 나타납니다.

file1
file2
file3

-exec세미콜론 ( find . -exec ls '{}' \;) 과 함께 사용하면

ls file1
ls file2
ls file3

그러나 더하기 부호 ( find . -exec ls '{}' \+)를 대신 사용하면 가능한 한 많은 파일 이름이 단일 명령에 인수로 전달됩니다.

ls file1 file2 file3

파일 이름의 수는 시스템의 최대 명령 줄 길이에 의해서만 제한됩니다. 명령이이 길이를 초과하면 명령이 여러 번 호출됩니다.


1
감사. 결과 파일을 정렬 할 때 매우 유용합니다. find -maxdepth 1 -type f -mtime -1 -exec ls -ltr {} \ +
fbas

1
멍청한 질문 : +관련 -exec이 항상 이스케이프되었지만 +관련 -mtime이 없음을 알았습니다 . 이유를 아십니까? ;과 관련하여 탈출하는 습관이 있다고 생각합니다 -exec.
kevinarpe

3
실제로 @kevinarpe, 나는 그것을 습관화하기 위해 그것을 분필 것입니다 ;. 탈출해야한다고 상상할 수 없다+
Martin

36

지금까지의 모든 대답은 정확합니다. 내가 사용하여 설명되어있는 문제의 (나에게) 명확 시위로이 제공 echo보다는 ls:

세미콜론을 사용하면 echo파일 (또는 다른 파일 시스템 객체)이 발견 될 때마다 명령 이 한 번 호출됩니다.

$ find . -name 'test*' -exec echo {} \;
./test.c
./test.cpp
./test.new
./test.php
./test.py
./test.sh

더하기 명령 echo은 한 번만 호출됩니다. 발견 된 모든 파일은 인수로 전달됩니다.

$ find . -name 'test*' -exec echo {} \+
./test.c ./test.cpp ./test.new ./test.php ./test.py ./test.sh

find많은 수의 결과가 나오면 호출되는 명령이 여러 개의 인수에서 질식되는 것을 알 수 있습니다.


1
쉘에 안전하게 전달할 수있는 숫자에만 결과를 추가하지 않아야합니까? 적어도 무엇을 하는가 xargs... 원칙적으로 너무 많은 주장을 질식 시키지는 않는다.
Rmano

1
@Rmano : 솔라리스에서 본 find(및 xargs)는 소비 할 수있는 것보다 더 많은 인수를 내 보냅니다 . GNU findutilsxargs(그리고 find)는 더 현명하게 행동하는 것처럼 보이지만 모든 사람이 GNU를 사용하는 것은 아닙니다.
Johnsyweb

2
@Johnsyweb, 모든 POSIX find는 인수 수의 한계에 도달하지 않도록 시도합니다. 그리고 여기에는 Solaris가 포함됩니다 (적어도 10 개). 실패 할 수있는 곳은 find ... -exec ksh -c 'cmd "$@" "$@"' sh {} +또는 과 같은 것을 find ... -exec ksh -c 'files="$*" cmd "$@"' sh {} +하지만 find실제로는 그것을 비난 할 수 없습니다. GNU findfind지원을위한 마지막 구현 중 하나입니다 +(스크립트를 GNU 시스템으로 이식하는 데 어려움을 겪었 음).
Stephane Chazelas

19

보낸 사람 man find:

-exec 명령;

명령을 실행하십시오. 0 상태가 반환되면 true입니다. 찾을 다음의 모든 인수는 ';'로 구성된 인수까지 명령에 대한 인수로 간주됩니다. 발생합니다. 문자열 '{}'은 (는) 일부 버전의 find에서와 같이 단독 인수가 아닌 명령 인수에서 발생하는 모든 위치에서 처리되는 현재 파일 이름으로 바뀝니다. 이 두 구조는 모두 쉘에서 확장되는 것을 막기 위해 이스케이프 처리 ( '\')하거나 인용해야합니다. '-exec'옵션 사용의 예는 EXAMPLES 섹션을 참조하십시오. 지정된 명령은 일치하는 각 파일마다 한 번씩 실행됩니다. 명령은 시작 디렉토리에서 실행됩니다. -exec 옵션 사용과 관련하여 피할 수없는 보안 문제가 있습니다.

-exec 명령 {} +

-exec 옵션의이 변형은 선택된 파일에서 지정된 명령을 실행하지만 명령 행은 선택한 각 파일 이름을 끝에 추가하여 빌드됩니다 . 명령의 총 호출 수는 일치하는 파일 수보다 훨씬 적습니다. 명령 행은 xargs가 명령 행을 빌드하는 것과 거의 같은 방식으로 빌드됩니다. 명령 내에서 하나의 '{}'인스턴스 만 허용됩니다. 명령은 시작 디렉토리에서 실행됩니다.

따라서 내가 이해하는 방식 \;은에서 찾은 각 파일에 대해 별도의 명령을 실행하는 find반면 \+파일을 추가하고 모든 파일에 대해 단일 명령을 실행합니다. 는 \이 그래서, 이스케이프 문자입니다 :

ls testdir1; ls testdir2 

vs

ls testdir1 testdir2

내 셸에서 위의 작업을 수행하면 질문의 출력이 반영됩니다.

사용하고 싶을 때의 예 \+

두 파일을 가정, 1.tmp그리고 2.tmp:

1.tmp :

1
2
3

2.tmp :

0
2
3

\;:

 find *.tmp -exec diff {} \;
> diff: missing operand after `1.tmp'
> diff: Try `diff --help' for more information.
> diff: missing operand after `2.tmp'
> diff: Try `diff --help' for more information.

를 사용하는 경우 \+(의 결과를 연결하기 위해 find) :

find *.tmp -exec diff {} \+
1c1,3
< 1
---
> 0
> 2
> 30

따라서이 경우에는 사이의 차이점 diff 1.tmp; diff 2.tmpdiff 1.tmp 2.tmp

여기서 경우가 있습니다 \;적절한 지와 \+필요합니다. \+with를 사용하면 rm많은 파일을 제거하는 경우 성능 (속도)이보다 우수합니다 \;.


맨 페이지도 읽을 수 있습니다. 그리고 나는했지만 사용의 차이점을 이해하지 못한다고 생각합니다. vs +
Ankur Agarwal

나는 -1이 공정하다고 생각하지 않는다. 나는 그 남자에 대한 나의 이해를 설명했다. 난 그냥 남자를 복사하고 떠나지 않았습니다. 더 나은 예제를 포함하도록 응답을 편집했습니다.
matchew

10

find특별한 구문이 있습니다. {}찾은 파일의 경로 이름으로 찾을 의미가 있기 때문에 그대로 사용 하고 (대부분) 셸은 다른 방식으로 해석하지 않습니다. \;세미콜론은 쉘에 의미가 있기 때문에 백 슬래시가 필요합니다 find. 따라서 findC 프로그램에 전달 된 인수 목록에서 쉘이 완료된 후보고 싶은 것은

"-exec", "rm", "{}", ";"

그러나 \;쉘을 통해 인수에 세미콜론을 가져 오려면 명령 행에 필요 합니다.

\{\}쉘 인용 해석 \{\}이 그냥 있기 때문에 벗어날 수 있습니다 {}. 마찬가지로 '{}'을 (를) 사용할 수 있습니다.

당신이 할 수없는 것은 사용입니다

 -exec 'rm {} ;'

쉘은 이것을 하나의 인수 로 해석하기 때문에

"-exec", "rm {};"

rm {} ;명령의 이름이 아닙니다. (적어도 누군가가 정말로 조이고 있지 않는 한)

최신 정보

차이점은

$ ls file1
$ ls file2

$ ls file1 file2

+명령 줄에 이름을 catenating된다.


1
나는 당신이 말하는 것을 이해합니다. 사용하는 것의 차이점을 묻습니다. vs +
Ankur Agarwal

1
미안하지만 내 질문이나 내 의견을주의 깊게 읽었습니까? 문구를 바꿔야 할 수도 있습니다. find에서 exec와 함께 세미콜론을 사용할 때와 find에서 exec와 함께 plus를 사용할 때 왜 다른 o / p가 있습니까?
Ankur Agarwal

2
이것은 왜 명령이 이와 같은지에 대한 훌륭한 설명입니다. 감사!
Sherwin Yu

1

;(세미콜론) 또는 +(더하기 부호) 의 차이점 은 인수가 find의 -exec/ -execdir매개 변수 로 전달되는 방식 입니다. 예를 들면 다음과 같습니다.

  • using ;은 여러 명령을 실행합니다 (각 인수마다 별도로).

    예:

    $ find /etc/rc* -exec echo Arg: {} ';'
    Arg: /etc/rc.common
    Arg: /etc/rc.common~previous
    Arg: /etc/rc.local
    Arg: /etc/rc.netboot
    

    다음의 모든 인수 find는 명령에 대한 인수로 간주됩니다.

    문자열 {}은 처리중인 현재 파일 이름으로 바뀝니다.

  • 를 사용 +하면 가능한 최소한의 명령이 실행됩니다 (인수가 결합되어 있기 때문에). xargs명령의 작동 방식과 매우 유사 하므로 한 줄에 최대 인수 제한을 초과하지 않도록 명령 당 가능한 많은 인수를 사용합니다.

    예:

    $ find /etc/rc* -exec echo Arg: {} '+'
    Arg: /etc/rc.common /etc/rc.common~previous /etc/rc.local /etc/rc.netboot
    

    명령 행은 선택한 각 파일 이름을 끝에 추가하여 빌드됩니다.

    {}명령 내에서 하나의 인스턴스 만 허용됩니다.

또한보십시오:


-5

하우스 키핑을위한 파일을 찾으려고했습니다.

찾기 . -exec echo {} \; 명령 결과는 결국 밤새 실행되었습니다.

찾기 . -exec echo {} \ + 결과가 있으며 몇 시간 밖에 걸리지 않았습니다.

도움이 되었기를 바랍니다.


2
이 답변은이 두 가지 방법이 어떻게 작동하고 결과가 어떻게 다른지 설명하지 않습니다.
misko321
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.