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


206

나는 오늘 명령으로 도움을 받았지만 작동하지 않는 것 같습니다. 이것은 명령입니다 :

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 && rm {}\;

껍질은 반환

find: missing argument to `-exec'

내가 기본적으로하려고하는 것은 재귀 적으로 디렉토리를 거치고 (다른 디렉토리가있는 경우) .rm파일 유형 에서 ffmpeg 명령을 실행하고 파일 유형으로 변환하는 것 .mp3입니다. 이 작업이 완료되면 .rm방금 변환 된 파일을 제거하십시오 .

이것에 대한 도움을 주셔서 감사합니다.

답변:


340

-exec명령은 종료되어야합니다 ;(당신이 일반적으로 입력해야하므로 \;하거나 ';'또는 피하기 쉘에 의해 interpretion에) +. 차이점은을 사용 ;하면 파일 당 한 번 명령이 호출 +되고 모든 파일 이름이 가능한 한 적은 횟수로 호출됩니다 (일반적으로 한 번이지만 명령 행의 최대 길이가 있으므로 분할 될 수 있음) . 이 예제를보십시오 :

$ cat /tmp/echoargs
#!/bin/sh
echo $1 - $2 - $3
$ find /tmp/foo -exec /tmp/echoargs {} \;
/tmp/foo - -
/tmp/foo/one - -
/tmp/foo/two - -
$ find /tmp/foo -exec /tmp/echoargs {} +
/tmp/foo - /tmp/foo/one - /tmp/foo/two

명령에 두 가지 오류가 있습니다.

먼저을 사용 {};하지만 ;고유 한 매개 변수 여야합니다.

둘째, 명령은에서 끝납니다 &&. "run find를 지정하고 성공한 경우 {};." 라는 파일을 제거하십시오 . -exec명령 에서 쉘을 사용하려면 다음과 같은 쉘에서 명시 적으로 실행해야합니다 -exec sh -c 'ffmpeg ... && rm'.

그러나 bash 명령 안에 {}를 추가해서는 안되며 특수 문자가있을 때 문제가 발생합니다. 대신 다음에 추가 매개 변수를 쉘에 전달할 수 있습니다 -c command_string(참조 man sh).

$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)

$첫 번째 예제에서 쉘에 의해 평가되는 것을 볼 수 있습니다 . $(rm -rf /):-) 라는 파일이 있다고 상상해보십시오.

(측면 참고 : -는 필요하지 않지만 명령 후 첫 번째 변수는 variable에 할당됩니다.이 변수 $0는 일반적으로 실행중인 프로그램의 이름을 포함하고 매개 변수로 설정하는 것이 약간 부정확하지만 아마 여기에 아무런 해를 끼치 지 않기 때문에 우리는 그것을 그냥 -시작하고 시작합니다 $1.)

그래서 당신의 명령은

find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;

그러나 더 좋은 방법이 있습니다. 지원을 찾으면 다음 andor같은 작업을 수행 할 수 있습니다 find -name foo -or -name bar. 그러나 -exec명령 과 함께 작동 하면 명령이 성공적으로 종료되면 true 로 , 그렇지 않으면 false로 평가됩니다. 이 예제를보십시오 :

$ ls
false  true
$ find * -exec {} \; -and -print
true

그것은 단지 그것을 위해 한 명령이 성공적이라면 인쇄, 실행 true하지만 대한을 false.

따라서으로 연결된 두 개의 exec 문을 사용할 수 -and있으며 전자가 성공적으로 실행 된 경우에만 후자를 실행합니다.


3
열쇠는 Marian의 ";; 자체에 대한 주장입니다"라는 줄로 보입니다. 그것은 전구와 현명한 코드 코드입니다. 감사.
pjammer

3
그것은 내가 -exec에서 읽은 최고의 설명에 관한 것입니다. 그것은 매우 강력하지만 항상 올바른 구문을 얻는 것이 어렵다는 것을 알았습니다. 이로 인해 몇 가지 사항이 훨씬 명확 해졌습니다. 특히 별도의 쉘에 명령을 래핑합니다. 좋은. 감사.
Eurospoofer

3
그 참고 -and하고 -or이식 할 수 없습니다. POSIX는 및를 지정 -a하며-o 실제로 -a는 항상 가정되므로 (필요하지는 않습니다).
gniourf_gniourf

또한 종료 자 앞에 공백이 있어야합니다. 예는 "\;"작동하지 않지만 " \;"않습니다
frmdstryr

56

나는 지금 그것을 알아 냈습니다. exec에서 두 개의 명령을 실행해야 할 경우 실제로 두 개의 별도 exec가 있어야합니다. 이것은 마침내 나를 위해 일했습니다.

find . -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 \; -exec rm {} \;

파일 변수를 삭제할지 확실하지 않습니까? 이것이 사실인지 아는 사람이 있습니까?
Abs

7
이러한 것들을 테스트하려면 echo명령 앞에을 추가하고 그 기능을 확인하십시오.
Marian

2
@Marian은 echo매우 신뢰할 수 - 당신은 차이를 말할 수 없다 echo "one argument"하고 echo one argument(실제로 전달하는 것으로의 후자의 출력은 거짓 인 echo두 개의 완전히 분리 된 인수). -exec bash -c 'printf "%q " "$@"' _ ffmpeg -i {} -sameq {}.mp3 \; -printf '\n'인쇄 할 수없는 문자를 표시하는 방식으로 출력을 인쇄하여 DOS 줄 바꿈 및 기타 이상한 점을 감지 할 수 있는 것과 같은 작업을 수행하는 것이 훨씬 좋습니다 .
Charles Duffy

52

각 \ 앞에 공백을 두십시오.

공장:

find . -name "*.log" -exec echo {} \;

작동하지 않습니다 :

find . -name "*.log" -exec echo {}\;

1
이것은 나를 자주 여행합니다. 요즘에는 기본적으로 공백을 추가하겠습니다.
harperville

저에게 그것은 Windows 7의 Cygwin에서 정반대로 작동합니다. 공간과 함께 작동-하지 않습니다. 그러나 \를 제거하면 앞에 공백이 있습니다. 그것은 전에, 그리고 공간없이 작동합니다; 여기에 설명 된 방식이 아닙니다.
WebComer

7

참고
로 Cygwin 시스템에서 "find -exec"명령 (Windows에서 유닉스 에뮬레이트 됨)을 사용하여 세미콜론 앞의 백 슬래시를 제거해야합니다.
find ./ -name "blabla" -exec wc -l {} ;


정말 혼란 스러웠습니다. find /etc/nginx -name '*.conf' -exec echo {} ;find /etc/nginx -name '*.conf' -exec echo {}\;같은 결과를 주었다. :(
Kirby

Windows 용 Git과 함께 제공되는 Bash 쉘을 실행 중이며 Dustin Cowles의 답변이 효과적입니다. 즉, 인용 부호 없음, 백 슬래시는 공백 뒤에 세미콜론으로 이스케이프 처리됩니다 {}.
mamacdon

의미에는 차이가 없지만 어떤 경우에는 백 슬래시를 넣어야하고 어떤 경우에는 넣을 수 없으며 다른 경우에는 선택할 수도 있습니다.
Dominique

2

Amazon Opsworks Chef bash 스크립트에서 비슷한 "missing -exec args"가 표시되는 경우를 대비하여 \를 이스케이프하기 위해 다른 백 슬래시를 추가해야했습니다.

bash 'remove_wars' do
  user 'ubuntu'
  cwd '/'
  code <<-EOH
    find /home/ubuntu/wars -type f -name "*.war" -exec rm {} \\;
  EOH
  ignore_failure true
end

2

또한 다른 사람이 "find : -exec에 대한 인수 누락"이 있으면 다음과 같이 도움이 될 수 있습니다.

일부 쉘에서는 이스케이프 처리를 수행 할 필요가 없습니다. 즉, ";"앞에 "\"가 필요하지 않습니다.

find <file path> -name "myFile.*" -exec rm - f {} ;

2
;인용 또는 여기에 탈출이 읽을, 쉘없는 소비 될 수 있다는 것을 의미하지 find. 또한, -f- f다른 두 가지입니다.
Charles Duffy

1

당신은 내가 생각하는 탈출을해야합니다.

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} \-sameq {}.mp3 \&\& rm {}\;

0

{}와 &&는 모두 명령 행으로 확장되어 문제를 일으킬 수 있습니다. 시도해 볼 것을 제안합니다.

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i \{} -sameq \{}.mp3 \; -exec rm \{} \;

exec의 첫 번째 명령이 성공하고 exec의 두 번째 명령이 실행 된 경우에도 {}올바른 파일을 삭제 하기 위해 변수에 액세스 할 수 있습니까?
Abs

무엇을 thinik으로 {}확장합니까? 두 개의 점이나 쉼표가 포함되어 있지 않으면 그대로 유지됩니다.
Marian

0

{}와 사이에 공백을 넣어야합니다\;

따라서 명령은 다음과 같습니다.

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 && rm {} \;

-4

"find : missing argument to -exec"가 계속 표시되면 execute 인수를 따옴표로 묶어보십시오.

find <file path> -type f -exec "chmod 664 {} \;"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.