将带有空格和引号的参数传递给脚本(不引用所有内容)

将带有空格和引号的参数传递给脚本(不引用所有内容)

以下内容在命令行上效果很好:

$ 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|

相关内容