공백과 따옴표를 사용하여 스크립트에 인수 전달(모든 것을 인용하지 않음)

공백과 따옴표를 사용하여 스크립트에 인수 전달(모든 것을 인용하지 않음)

다음은 명령줄에서 제대로 작동합니다.

$ ffmpeg -i input.m4a -metadata 'title=Spaces and $pecial char'\''s' output.m4a

이 명령을 어떻게 매개변수화하고 스크립트/함수에서 사용할 수 있습니까? 다음과 같이 여러 메타데이터 태그를 추가하고 싶습니다.

$ set-tags.sh -metadata 'tag1=a b c' -metadata 'tag2=1 2 3'

고쳐 쓰다:

내 질문을 너무 단순화하고 있습니다. 실제로 매개변수화된 명령을 사용하여 스크립트를 호출하는 스크립트를 호출하고 싶습니다.

이것이 나의 정확한 사용 사례입니다.

이 함수는 파일을 오디오북 형식(.profile에 정의됨)으로 변환합니다.

# snippet of .profile
convert_to_m4b () {
    FILE="$1"
    BASENAME=${FILE%.*}; shift

    ffmpeg -i "$FILE" -vn -ac 1 -ar 22050 -b:a 32k "$@" tmp.m4a &&
    mv tmp.m4a "$BASENAME.m4b"
}; export -f convert_to_m4b

Convert_to_m4b 함수는 download-and-convert.sh에서 호출됩니다.

#/bin/sh
 MP3_URL=$1; shift
FILENAME=$1; shift

if [ ! -f "${FILENAME}.mp3" ]; then
    curl --location --output "${FILENAME}.mp3" "$MP3_URL"
fi

convert_to_m4b "${FILENAME}.mp3" "$@"

Download-and-convert.sh는 process-all.sh에서 호출됩니다.

#/bin/sh
download-and-convert.sh http://1.mp3 'file 1' -metadata 'title=title 1' -metadata 'album=album 1'
download-and-convert.sh http://2.mp3 'file 2' -metadata 'title=title 2' -metadata 'album=album 2'
...
...
download-and-convert.sh http://3.mp3 'file N' -metadata 'title=title N' -metadata 'album=album N'

ffmpeg에서 다음 오류가 발생합니다.

[NULL @ 00000000028fafa0] Unable to find a suitable output format for ''@''
'@': Invalid argument

"$@"함수를 호출하는 대신 download-and-convert.sh에서 Convert_to_m4b를 인라인하면 작동합니다.


따옴표가 누락되어 공백이 있는 인수가 잘못 분할되므로 다음은 작동하지 않습니다.

#/bin/sh
ffmpeg -i input.m4a $@ output.m4a

다양한 방법을 시도해봤지만인용하다$@, 그러나 이것도 '-metadata'인용으로 끝나므로 명령줄 인수가 올바르게 인식되지 않습니다.

나는 단지 각 매개변수 주위에 따옴표를 붙이기를 원한다고 생각합니다(매개변수가 처음에 따옴표로 묶인 경우). bash는 스크립트/함수에 인수를 전달하기 전에 따옴표를 제거하기 때문에 이는 어려운 것 같습니다.

-metadata아니면 주장을 전달하는 더 좋은 방법이 있습니까 ? (예: 환경 변수 또는 파일)

답변1

"$@"당신이 그것을 고수하는 한 그것은 당신의 요구를 완벽하게 충족시킬 것입니다. 여기 당신을 위한 작은 실험이 있습니다:

  • script1.sh:

    #! /bin/sh
    ./script2.sh "$@"
    
  • script2.sh:

    #! /bin/sh
    ./script3.sh "$@"
    
  • script3.sh:

    #! /bin/sh
    printf '|%s|\n' "$@"
    

이를 통해 논쟁은 방해받지 않고 그대로 유지됩니다.

$ ./script1.sh -i input.m4a -metadata "title=Spaces and \$pecial char's" output.m4a
|-i|
|input.m4a|
|-metadata|
|title=Spaces and $pecial char's|
|output.m4a|

관련 정보