내 스크립트가 제대로 작동하지 않는 이유는 무엇입니까?

내 스크립트가 제대로 작동하지 않는 이유는 무엇입니까?

나는 ./script.sh다음과 같이 내 것을 사용하려고합니다 :

./compile.sh -n NAME_ALBUM -f 000 000 000 000 -l 000 000 000 000
  • 어디-NALBUM_NAME이고 저장되는 출력 파일 이름에 해당합니다.
  • 어디-에프의미 First는 재생 목록에서 가장 먼저 나타나는 비디오 파일 이름 목록입니다.
  • 어디-엘의미 Last는 재생 목록의 마지막 비디오 파일 이름 목록입니다.

그런 다음 재생 목록이 공급됩니다 ffmpeg...

#!/bin/sh

# usage: ./compile.sh -n NAME_ALBUM -f 000 000 000 000 -l 000 000 000 000
# OPTION -n is for NAME, video file NAME.
# OPTION -f is for FIRST, video numbers to come FIRST in playlist.
# OPTION -l is for LAST, video numbers to come LAST in playlist.
# NOTE: mp4 videos are numbered as 001.mp4, 002.mp4, 003.mp4
# NOTE: if no videoss are mentioned in -f or -l then it will be ignored by default.
# Q1: possible to use more than (4) videos in -f or -l ?

while getopts ":n:f:l:" options; do

  case "${options}" in
    n)
      $1=${OPTARG}
      ;;
    f)
      $2=${OPTARG}
      ;;
    l)
      $3=${OPTARG}
      ;;
    h)
      echo "Help contents:
            ./compile.sh -n NAME_ALBUM -f 000 000 000 000 -l 000 000 000 000"
      ;;
    :) # not sure what this is
      echo "Error: -${OPTARG} requires an argument." #not sure what this is
      exit_abnormal
      ;;
    *) # or what this ones for
      exit_abnormal
      ;;
  esac
done
exit 0

# mp4 video file name that gets compiled
COMPILED=$1_$(date +'%Y-%m-%d_%H:%M:%S')

# video playlist fed to ffmpeg
VIDEO_LIST=list_$(date +'%Y-%m-%d_%H:%M:%S').txt


find *.mp4 | sed 's:\ :\\\ :g' | sed 's/^/file /' | sort -R  > $VIDEO_LIST; (printf 'g?%s?m0\n' $2 ; printf 'wq\n') | ed -s $VIDEO_LIST; ( printf 'g?%s?m$\n' $3 | tac; echo 'wq'; ) | ed -s $VIDEO_LIST; ffmpeg -f concat -i $VIDEO_LIST -c:v libx264 -crf 12 -preset slow -c:a copy $COMPILED.mp4

내 스크립트가 작동하지 못하게 하는 것은 정확히 무엇입니까?

Q: 이 스크립트의 역할은 정확히 무엇인가요?

해당 디렉토리의 비디오를 포함하는 ffmpeg에 필요한 재생 목록을 생성하고(비디오 이름을 001.mp4, 002.mp4 등으로 바꾸는 것이 더 낫습니다. 이렇게 하면 추가 "첫 번째/마지막" 옵션을 더 쉽게 사용할 수 있습니다) 모든 항목을 섞습니다. 비디오 재생 목록의 비디오를 ffmpeg에 제공하여 하나의 비디오로 컴파일합니다. 추가 옵션: 특정 동영상을 재생목록의 첫 번째 또는 마지막에 추가해야 하는 경우 숫자를 입력하세요. 스크립트를 실행할 때 명령줄에 파일 이름을 씁니다.

답변1

John1024가 언급한 것 외에도 유사한 매개변수는 -f file1 file2 file3실제로 다음과 같이 읽혀집니다 -f file1. 첫 번째 값만 스크립트로 읽히고 다른 값은 손실됩니다. 당신의 -l주장도 마찬가지다.

당신이 할 수 있는 일은 실제로 값의 목록인 문자열을 지정하는 것입니다(값 주위의 작은따옴표에 유의하십시오).

./compile.sh -n NAME_ALBUM -f 'file1 file2 file3' -l 'file7 file8 file9'

이렇게 하면 다음이 수행됩니다.

  • 귀하의 옵션 값은 " " -f입니다 .file1 file2 file3
  • 귀하의 옵션 값은 " " -l입니다 .file7 file8 file9

파일 이름을 얻기 위해 "단지" 분할합니다. 다음과 같은 구조가 여러분에게 영감을 줄 것입니다.

f='file1 file2 file3'; for fileName in $f; do echo "$fileName"; done

댓글로 질문 후 편집:

사용 중에 견적이 필요합니까? 아니면 스크립트에 숨겨질 수 있나요? 이미 생각했지만 스크립트의 명령줄 사용 중에 사용해야 한다고 생각했는데 이는 제가 원하는 것이 아닙니다.

이것은 나에게 완전히 명확하지는 않지만 다음과 같이 말할 수 있습니다.

  • 'file1 file2 file3'(따옴표 포함)은 단일 문자열(공백 포함)이며 변수에 저장하거나 매개변수(예 -f <value>:
  • file1 file2 file3(따옴표 제외)는 3개의 다른 문자열입니다(공백이 매개변수 구분 기호 역할을 하기 때문). -f <value>위와 같은 해킹(예: 따옴표)을 사용하지 않는 한 구성의 단일 매개변수에 3개의 값을 전달할 수 없습니다 .

또한 $2 $3 $4 $5는 -f로, $6 $7 $8 $9는 -l로 사용하는 것은 어떻습니까?

getopts구문과 매개변수를 혼합하면 $n결국 읽을 수 없는 스크립트가 생성됩니다. 게다가 이 $n전략에는 정확히 4개의 가치 -f와 4개의 가치가 포함됩니다 -l.

내 제안은 여전히 -f​​및 옵션에 대한 -l파일 목록을 제공 'file1 file2 file3'하고 스크립트에서 해당 목록을 잘라내는 것입니다.

답변2

|이를 줄의 마지막 문자 로 사용할 수 있으며 줄은 계속됩니다.

예를 들어

foo | bar | wc

동등하다

foo |
bar |
wc
  • 개행 문자처럼 명령을 구분 한다는 점에 유의하세요 ;.

스크립트의 마지막 부분을 들여쓰기하고 외부에 새 줄을 삽입한 |다음;

마지막 줄은 다음과 같습니다.

find *.mp4 |
 sed 's:\ :\\\ :g' |
 sed 's/^/file /' | 
 sort -R  > $VIDEO_LIST

 (printf 'g?%s?m0\n' $2 ; printf 'wq\n') |
 ed -s $VIDEO_LIST

 ( printf 'g?%s?m$\n' $3 | tac; echo 'wq'; ) |
 ed -s $VIDEO_LIST

 ffmpeg -f concat -i $VIDEO_LIST -c:v libx264 -crf 12 -preset slow -c:a copy $COMPILED.mp4
  • $2어디서 $3? 명령줄? 사용set alpha bravo charly ? (다른 답변에서 이 문제를 해결합니다)

  • '\n'두 번째 sed에서 뭔가 빠진 것 같습니다 .

  • 모험가가 되십시오. 스크립트를 다음 주소로 제출하세요.https://codereview.stackexchange.com/

관련 정보