![공백과 따옴표를 사용하여 스크립트에 인수 전달(모든 것을 인용하지 않음)](https://linux55.com/image/117462/%EA%B3%B5%EB%B0%B1%EA%B3%BC%20%EB%94%B0%EC%98%B4%ED%91%9C%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%97%90%20%EC%9D%B8%EC%88%98%20%EC%A0%84%EB%8B%AC(%EB%AA%A8%EB%93%A0%20%EA%B2%83%EC%9D%84%20%EC%9D%B8%EC%9A%A9%ED%95%98%EC%A7%80%20%EC%95%8A%EC%9D%8C).png)
다음은 명령줄에서 제대로 작동합니다.
$ 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|