2014-08-09 5 views
1

* .avi 파일을 mp4 형식으로 변환해야하는 스크립트를 작성했습니다. 그러나 "while"루프는 첫 번째 반복 후에 중지됩니다. 나는 놀랐어요BASH에서 첫 번째 반복 후 루프가 중지됨

find . -name a.avi b.avi.c.avi d.avi ... -type f 

당신이 'didn를 : 같은 find 명령 보이는, 그래서 find . -name *.avi -type f

이 쉘은find 시작하기 전에 와일드 카드 을 확대 :

#!/bin/bash 
shopt -s lastpipe 

cd <some_directory> 

find . -name *.avi -type f | 
    while read -r avi 
    do 
     /usr/bin/HandBrakeCLI -i "${avi}" -o "${avi%.avi}.mp4" -f mp4 -m -O -e x264 -q 20 --vfr \ 
#  &> /dev/null 
     if [ "$?" -eq 0 ] 
     then 
      echo "${avi} was converted successfully" 
      rm "${avi}" 
     else 
      echo "${avi} was not converted" 
      break 
     fi 
    done 
+0

질문을 추가해야합니다. – witrin

+0

때문에 'break' 문이 필요합니까? BTW,'done <(find ...)'를 사용하는 것은'lastpipe'와 동일하고 _more common_입니다. :) – jm666

답변

1

이 부분은 잘못 t "find : 경로가 expression : b.avi 앞에 와야 함"과 같은 오류 메시지가 표시됩니다.

그는 셸에서 별표를 찾을 수 있으므로 자체 확장이 가능합니다.

중 하나를 선택하십시오.
find . -name \*.avi -type f 
find . -name '*.avi' -type f 

당신이 GNU 시스템에 있는지 여부는 언급하지 않았습니다. 루프가 앞이나 뒤에 공백이있는 파일 이름에 의해 위험에 빠질 위험이 있습니다. 이것을 시도하십시오 :

find . -name \*.avi -type f -print0 | while read -rd '' avi; do ... 
+0

앞/뒤 공백을 유지하기 위해 IFS를 설정하는 것을 잊었습니다. IFS = read -rd "avi; 해라. – lihao

0

HandBrakeCLI 또한 첫 번째 인스턴스가 호출 된 후 루프 끝을 읽는 입력을 읽는 중일 수 있습니다. bash를 사용하고 있으므로, 다른 파일 설명자로 방향 재 지정된 입력으로 프로세스 대체를 사용할 수 있습니다. 사용 4이 예에서 :

while read -ru 4 avi; do 
    ... 
done 4< <(exec find . -name *.avi -type f) 

내 선호하는 버전도 readarray를 사용하는 것입니다. 그들은 줄 바꿈이 어디 불규칙한 파일 이름을 대상으로하지 않는 경우는 매우 충분 :

readarray -t files < <(exec find . -name *.avi -type f) 
for avi in "${files[@]}"; do 
    ... 
done 
또 다른 방법은 아마도 /dev/nullHandBrakeCLI의 입력을 리디렉션하는 것입니다

:

</dev/null /usr/bin/HandBrakeCLI ... 

다른 제안 :

  1. 견적 -name 패턴 : '*.avi'
  2. IFS= 앞뒤 공백을 제거하지 못하도록하십시오. IFS= while read ...
관련 문제