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

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 '{}' \+
  • 이전 버전의 GNU find를 사용 중일 수 있습니다. -exec cmd {} + 변형은 POSIX이고 80 년대부터 사용 가능했지만 GNU find는 최근 (2005 년)에만 추가했습니다. find --version가 무엇을 알려 줍니까?
  • @Koveras, 그러면 그게 될 것입니다. -exec {} +는 2005 년에 4.2.12에 추가되었습니다. 이전 GNU 발견에서 (비 POSIX) -print0 | xargs -r0를 사용하여 무언가를 얻을 수 있습니다. 비슷한. 4.1는 1994 년부터입니다.
  • JRFerguson은 -name 패턴이 삭제 된 답변에서 지적했습니다. 인수는 따옴표로 묶어야합니다 : -name "*.c" -o -name "*.h". -exec 오류와 관련이 없지만 사실입니다. Gilles 만 언급하지만 다른 모든 답변에서는 와일드 카드를 따옴표로 묶은 것을 알 수 있습니다. … (계속)
  • (계속)… jlliagre의 대답은 설명없이 이름 표현식을 -name "*.[ch]"로 축소합니다. 이는 명령 줄을 단순화하고 특히 -o를 제거하는 이점이 있습니다. -o가 포함 된 찾기 표현식은 제대로 이해하기 어렵습니다. 당신의 것이 잘못되었습니다. Gilles의 답변에서와 같이 오류가 발생하지 않도록 명령이 수정되면 .h에서만 grep가 실행됩니다. 파일. '(' -name '*.c' -o -name '*.h' ')'를 수행해야합니다.

답변

따옴표 대신 사용 된 백틱 (질문에 대한 이후 편집에서 제거됨), 필요한 경우 따옴표 누락, 쓸모없는 추가 따옴표, 그룹 -o 절 및 find의 다양한 구현이 사용되었습니다 (자세한 내용은 주석 및 채팅 참조).

어쨌든 명령은 다음과 같이 단순화 할 수 있습니다.

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

또는 구식 GNU 찾기 버전을 사용하는 경우 항상 작동합니다.

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

댓글

  • 죄송합니다. 백틱이 아닌 인용문입니다.
  • {}는 셸에 특별한 의미가 없습니다.
  • 찾기 매뉴얼 페이지에서 : ” ‘ { } ‘는 find의 일부 버전에서와 같이 단독 인 인수뿐만 아니라 명령에 대한 인수에서 발생하는 모든 곳에서 처리되는 현재 파일 이름으로 대체됩니다. 이러한 구성은 모두 이스케이프 (‘ \ ‘ 사용)하거나 인용하여 쉘에 의한 확장으로부터 보호해야 할 수 있습니다. ”
  • 매뉴얼 페이지에서 실제로 읽었지만 사실 제가 알고있는 쉘이 ‘ 중괄호를 인용해야합니다. 어떤 셸을 사용하고 있습니까?
  • bash. 따옴표가 있든 없든 어쨌든 오류가 발생합니다.

답변

-exec는 일반적으로-exec에 대한 인수에 종결자가 없음을 의미합니다. 종결자는 ; 문자 만 포함하는 인수 여야합니다 (셸 명령에서 인용해야하므로 일반적으로 \; 또는 ";") 또는 {}+를 포함하는 두 개의 연속 인수.

p>

Stephane Chazelas는 -exec … {} +. / div>, -exec {} \; 만.GNU는 -exec … {} +를 늦게 채택했지만 덜 오래된 도구 모음 (예 : Cygwin a)을 사용하는 것이 좋습니다. >, git 및 훨씬 더 많은 것을 포함하거나 GNUwin32 는 git은 없지만 나쁜 직원이 사용하려고 시도하는 리눅스는 없습니다. -하지만 Cygwin이 제공하는 Windows 분위기).이 기능은 9 년 전에 버전 4.2.12에서 추가되었습니다 (GNU find를 만들기 위해 마지막으로 확인 된 기능이었습니다). POSIX 호환).

이전 GNU 찾기를 고수하려면 xargs -0 div와 함께 -print0를 사용할 수 있습니다. > 유사한 기능을 얻으려면 그룹화 된 명령 실행, 임의의 파일 이름 지원

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

find 명령 줄입니다. 그렇지 않으면 .c 파일이 포함 된 디렉터리에서이 명령을 실행하면 따옴표가없는 *.c 파일이 d는 현재 디렉토리의 .c 파일 목록으로 확장됩니다.

/dev/null

명령 줄은find가 단일 일치 항목을 찾더라도 grep이 항상 파일 이름을 인쇄하도록하는 트릭입니다. GNU 찾기를 사용하는 또 다른 방법은-H옵션을 전달하는 것입니다.

댓글

  • 무엇을합니까? cygwin이 제공하는 bad-employee-trying-to-use-linux-but-we-impose-windows 분위기를 의미합니까?
  • GNUwin32는 ‘ 기대하지 않았습니다. : (
  • 질문에 대한 내 의견을 참조하세요.
  • semi 주위의 따옴표는 package.json 스크립트 내에서 작동합니다.

답변

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 doe s는 지원하지 않습니다. 예 :

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" {} + 

. -c 플래그 다음에 bash의 특수 문자를 이중 이스케이프해야 할 수도 있습니다.

댓글

  • (1) 위의 질문에 실제로 답하는 부분은 이미 다른 사람들이 제공했습니다. (2) 설명하는 내용은 GNU find의 결함이나 결함이 아니라 POSIX에서 지정한 올바른 동작 a입니다. >.
  • +1 마지막으로 추가 매개 변수가 작동하지 않는 ‘ 이유에 답하는 사람입니다! POSIX 정의에 결함이있는 것 같습니다.
  • GNU가 ‘있는 경우 find ‘ GNU cp가있을 것입니다. 이 경우 find ... -exec cp --target-directory ~/.fonts {} + 실행 문자열 끝에 {}를 유지할 수 있습니다.

답변

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

오류 발생 find: missing argument to ``-exec".

{}\ 사이에 공백을 추가하면 문제가 해결되었습니다.

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

댓글

  • find 명령을 사용하세요.
  • 질문에서 내가 이해 한 것은, 괜찮습니다.하지만 문제는 동일합니다. ” find : missing argument to“-exec ‘ “, 문제가 다른 이유에서 발생할 수 있습니다. 동일한 문제 설명을 보았 기 때문에 대답했습니다.
  • @Kusalananda 좋은 슬픔, 멍청이는 OP가 질문의 제목과 본문 모두에 명시된보고 된 오류에 대한 해결책을 제공했습니다.
  • @bvj 질문은 명시 적으로 다룹니다. + 형식의 -exec 옵션을 find로 설정합니다. 이 답변은 질문을하는 사용자에게없는 문제를 수정하는 것입니다.

답변

과거에 exec 구문과 두통의 공유. 지금은 대부분의 경우 더 좋은 bash 구문을 선호합니다.

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

파일을 그룹으로 처리하려는 경우 각각이 순차적으로 평가되므로 몇 가지 제한이 있습니다. 하지만 출력을 다른 곳에서도 잘 파이프 할 수 있습니다.

코멘트

  • 이게 작동하는 경향이 있지만 순수 찾기 버전보다 훨씬 덜 유용합니다. 이름에 공백이있는 파일을 올바르게 처리 할 수 없습니다.
  • 아니요. ‘이 작업을 수행하지 마십시오. 파일에 공백 및 기타 “이상한”문자가 포함되는 즉시 중단됩니다. 이것은 또한 find … -exec … \;보다 더 복잡하고 느리므로 파일 이름이 다음과 같다는 것을 알고 있어도 ‘ 사용할 이유가 없습니다. 길들여졌습니다.
  • 이것은 파일 이름을 기반으로 여러 줄의 논리를 실행해야하는 상황에 유용했습니다 (문자 제거, 디렉토리 만들기 및 파일 이동). 하나의 exec에서 여러 가지 작업을 수행하려는 시도는 내가 여기에 소비하고 싶었던 5 분 동안 너무 골칫거리였습니다. 내 파일 이름이 길어졌고 이로 인해 문제가 해결되었습니다. 🙂

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다