찾기 : -exec에 대한 인수 누락


18

다음 명령을 실행하려고합니다.

find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' +

이것은 오류를 반환합니다 :

find: missing argument to -exec

이 명령의 맨 페이지와 일치하는 것처럼 보이는이 명령의 문제점을 볼 수 없습니다.

-exec 명령 {} +

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

나는 또한 시도했다 :

find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' '{}' +
find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar '{}' +
find a/folder b/folder \( -name *.c -o -name *.h \) -exec grep -I foobar '{}' +
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+

+끝에 탈출을 시도 했습니까 ? find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
— jayhendren

3
구버전의 GNU를 사용하고있을 수 있습니다 find. 이 -exec cmd {} +변종은 POSIX이며 80 년대부터 사용 가능 했지만 GNU는 최근에 상대적으로 최근에 추가 한 것만 발견했습니다 (2005). 무엇을 find --version말합니까?
— Stéphane Chazelas

2
@Koveras, 그럴 것입니다. -exec {} +구식 GNU 발견에서는 (비 POSIX) -print0 | xargs -r0를 사용하여 비슷한 것을 얻을 수 있습니다. 4.11994 년부터입니다
— 스테판 Chazelas가

1
JRFerguson은 -name패턴 인수가 인용되어야한다고 ( 삭제 된 답변으로) 지적했습니다 -name "*.c" -o -name "*.h". -exec오류 와 관련이 없지만 사실 입니다. Gilles만이 언급하지만 다른 모든 답변은 와일드 카드를 따옴표로 묶는 것을 알 수 있습니다. … (계속)
— G-Man, 'Reinstate Monica'라고

1
(계속)… jlliagre의 답변은 -name "*.[ch]"설명없이 이름 표현을 무너 뜨립니다 . 이것은 명령 행을 단순화하고 특히를 제거하는 이점이 있습니다  -o. 관련된 표현을 찾기 -o가 어렵습니다. 네 잘못이야. Gilles의 답변과 같이 오류가 발생하지 않도록 명령이 수정 grep되면 .h파일 에서만 실행 됩니다 . 해야합니다 '(' -name '*.c' -o -name '*.h' ')'.
— G-Man은 '복귀 상태 모니카'

답변:


18

주위에서 사용하는 작은 따옴표를 제거해야합니다 {}. 다음과 같이 명령을 단순화 할 수 있습니다.

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} +

구식 GNU 찾기 버전을 사용하는 경우에도 여전히 작동합니다.

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} \;

죄송합니다. 백틱이 아닌 따옴표입니다.
— David Kennedy

{}쉘에 특별한 의미가 없으므로 따옴표는 쓸모 가 없습니다.
— jlliagre

find 매뉴얼 페이지에서 : "문자열 '{}'은 (는) 일부 버전의 find에서와 같이 단독 인 인수가 아닌 명령의 인수에서 발생하는 모든 위치에서 처리되는 현재 파일 이름으로 대체됩니다. 쉘에 의한 확장을 막기 위해 구조물을 이스케이프 처리 ( '\')하거나 인용해야 할 수도 있습니다. "
— David Kennedy

1
나는 실제로 매뉴얼 페이지에서 그것을 읽었지만 사실은 중괄호를 인용해야한다는 것을 알고있는 껍질이 없다는 사실입니다. 어떤 쉘을 사용하고 있습니까?
— jlliagre

세게 때리다. 따옴표가 있거나 없거나 어쨌든 오류가 발생합니다.
— David Kennedy

10

"에 대한 인수 누락 -exec"은 일반적으로-에 대한 인수에 exec종결자가 누락 되었음을 의미합니다 . 터미네이터 중 단지 문자가 포함 된 인수 여야합니다 ;(그래서는 일반적으로 쓰여 쉘 명령에 인용 할 필요가, \;나 ';'), 또는 포함 된 두 개의 연속 인수 {}와 +.

스테판 Chazelas가이 확인했습니다 당신이 지원하지 않는 GNU의 발견 이전 버전 사용하고 있는지 -exec … {} +만, -exec {} \;. GNU가 늦게 채택되었지만 git 및 훨씬 더 많이 포함하는 Cygwin 또는 git가 없지만 직원이 부족한 GNUwin32-exec … {} + 와 같은 덜 골동품적인 도구 모음을 얻는 것이 좋습니다. Cygwin이 제공하는 Linux를 사용하지만 우리는 임프레스 윈도우 분위기를 사용합니다. 이 기능은 9 년 전에 버전 4.2.12에 추가되었습니다 (GNU POSIX 호환 을 위해 마지막으로 확인 된 기능이었습니다 ).find

당신이 이전 GNU 찾기에 충실하려는 경우, 당신은 사용할 수 있습니다 -print0에 xargs -0임의의 파일 이름을 지원하고, 그룹화 명령 실행 : 비슷한 기능을 얻을 수 있습니다.

find a/folder b/folder -name '*.c' -o -name '*.h' -print0 | xargs -0 grep -I foobar /dev/null

find명령 행 에서 항상 와일드 카드를 인용하십시오 . 그렇지 않으면 .c파일이 포함 된 디렉토리에서이 명령을 실행 하면 인용되지 않은 파일이 현재 디렉토리 *.c의 .c파일 목록으로 확장됩니다 .

명령 행에 추가 /dev/null하는 것은 하나의 일치하는 항목을 찾 grep더라도 grep이 항상 파일 이름을 인쇄하도록하는 속임수 find입니다. GNU find에서 다른 방법은 옵션을 전달하는 것 -H입니다.


1
cygwin이 제공하는 나쁜 직원이 사용하기 위해 리눅스를 시도하지만 임 포즈 윈도우 분위기는 무엇을 의미합니까?
— David Kennedy

GNUwin32는 기대하지 않습니다 :(
— David Kennedy

질문에 대한 내 의견을 참조하십시오.
— G-남자 '는 분석 재개 모니카'말한다

semi 주위의 따옴표는 package.json 스크립트 내에서 작동했습니다.
— bvj

2

다음과 같은 명령이

find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar {} +

오류를 반환

find: missing argument to -exec

가능한 원인은 너무 오래된 GNU이므로 find구문을 지원하지 않습니다 -exec mycommand {} +. 이 경우 여러 대상을 수집 -exec mycommand {} \;하고 mycommand한 번만 실행하는 대신 발견 된 모든 대상에 대해 한 번만 실행 되는 낮은 성능의 교체가 실행 됩니다 mycommand.

그러나 GNU find는 다음을 지원하지 않습니다.

find . -type f -and -name "*.ttf" -exec cp {} ~/.fonts +

GNU find는 {} +보다 일반적인 대신 리터럴 조합 만 지원 하기 때문 {} additional parameters +입니다. 중괄호와 +문자 사이에는 아무 것도 없어야 합니다. 이 작업을 시도하면 동일한 오류가 발생합니다.

find: missing argument to -exec

해결 방법은 {} additional parameters \;작동하지만 찾은 모든 대상에 대해 한 번씩 명령을 실행하는 구문을 사용 하는 것입니다. GNU에서 더 많은 성능을 필요로하는 경우 find, 주어진 인수에 추가 매개 변수를 추가 할 수있는 랩퍼 스크립트를 작성해야합니다. 같은 것

#!/bin/bash
exec mycommand "$@" additional parameters

충분해야합니다. 또는 임시 파일을 만들지 않으려면 한 줄짜리 줄을 사용하여 다음과 같이 매개 변수의 순서를 변경할 수 있습니다.

find . -type f -and -name "*.ttf" -exec bash -c 'mycommand "$@" extra arguments' {} +

실행 mycommand {list of ttf files} extra arguments됩니다. -c플래그 뒤에 bash에 특수 문자를 두 번 이스케이프해야 할 수도 있습니다 .


(1) 실제로 질문에 대답하는 위의 부분은 다른 사람들에 의해 이미 주어졌습니다. (2) 당신이 묘사하는 것은 GNU의 결함이나 결함이 find아니라 POSIX에 의해 지정된 올바른 행동 입니다.
— G-남자 '는 분석 재개 모니카'말한다

1
+1 마지막으로, 추가 매개 변수가 작동하지 않는 이유에 대한 답변을 제공하는 사람! POSIX 정의에 결함이있는 것 같습니다.
— Jonathan

GNU find를 가지고 있다면 아마도 GNU가있을 것입니다 cp. 이 경우 실행 문자열 끝에 find ... -exec cp --target-directory ~/.fonts {} +를 유지할 수 {}있습니다.
— roaima

1

find . -type f -perm 0777 -exec chmod 644 {}\;

오류가 발생했습니다 find: missing argument to ``-exec'.

사이에 공간을 추가 {}하고 \수정했습니다.

find . -type f -perm 0777 -print -exec chmod 644 {} \;


1
find해당 질문 의 명령 에는 그러한 문제가 없습니다 .
— Kusalananda

질문에서, 나는 이해하지 못했습니다. 그러나 문제는 동일합니다.
— ShreePool

@ Kusalananda 좋은 슬픔, 멍청한 놈은 질문의 제목과 본문 모두에 OP에 의해 명시된보고 된 오류에 대한 해결책을 제공했습니다.
— bvj

@bvj이 질문 +은에 대한 -exec옵션 형식을 명시 적으로 처리 합니다 find. 이 답변은 사용자가 질문하지 않은 문제를 해결합니다.
— Kusalananda

-1

과거에 exec 구문으로 두통을 겪었습니다. 이제는 더 좋은 bash 구문을 선호합니다.

for f in `find a/folder b/folder -name "*.[ch]"`; do grep -I foobar $f; done

각 파일이 순차적으로 평가되므로 파일을 그룹으로 취급하려는 경우 몇 가지 제한 사항이 있지만 출력을 다른 곳으로 파이프 할 수 있습니다


1
이것이 작동하는 경향이 있지만 이름에 공백이있는 파일을 올바르게 처리 할 수 ​​없기 때문에 순수 찾기 버전보다 유용성이 떨어집니다.
— Etan Reisner

5
아니, 이러지 마 파일에 공백과 다른“이상한”문자가 포함 되 자마자 중단됩니다. 이 방법은보다 복잡하고 느리 find … -exec … \;므로 파일 이름이 길다는 것을 알고 있어도이를 사용할 이유가 없습니다.
— Gilles 'SO- 악마 그만'

이것은 파일 이름을 기반으로 여러 줄의 논리를 실행 해야하는 상황에 도움이되었습니다 (문자 제거, 디렉토리 만들기 및 파일 이동과 같은). 한 번 exec에 여러 가지 일을하려고 하면 5 분 동안 너무 많은 두통을 겪었습니다. 내 파일 이름은 길
— 들였고
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.