bash脚本中的参数错误太多

fro*_*odo 6 bash shell

我已修改此脚本以从YouTube下载歌曲但我在运行时遇到以下错误:

sh youtube2mp3.sh https://www.youtube.com/watch?v=gpOJ6iu8fqQ
Run Code Online (Sandbox Code Playgroud)

错误:

youtube2mp3.sh: line 31: [: too many arguments
youtube2mp3.sh: line 39: [: too many arguments
youtube2mp3.sh: line 49: [: too many arguments
Sorry but the system encountered a problem.
Run Code Online (Sandbox Code Playgroud)

行号指的是if [ -f $video_title.$ext1 ]三行......我认为我的论点没有,因为它在以前的版本中有效,但我仍然坚持这一点 - 有人可以解释我需要做些什么来纠正它吗?

address=$1

video_title="$(python youtube-dl $address)"

ext1="flv"
ext2="mp4"
ext3="webm"



if [ -f  $video_title.$ext1 ]
then
    ffmpeg -i $video_title.$ext1 "$video_title".wav
    lame "$video_title".wav "$video_title".mp3
    rm $video_title.$ext1 "$video_title".wav
else
    if [ -f $video_title.$ext2 ]
    then
        ffmpeg -i $video_title.$ext2 "$video_title".wav
        lame "$video_title".wav "$video_title".mp3
        rm $video_title.$ext2 "$video_title".wav
    else    
        if [ -f $video_title.$ext3 ]
        then
            ffmpeg -i $video_title.$ext3 -acodec libmp3lame -aq 4 "$video_title".mp3
            rm $video_title.$ext3
        else
            echo "Sorry but the system encountered a problem." 
        fi

    fi
fi
Run Code Online (Sandbox Code Playgroud)

che*_*ner 8

始终引用参数扩展.值$video_title被分成多个单词,这会混淆[命令.

if [ -f "$video_title.$ext1" ]
then
     ffmpeg -i "$video_title.$ext1" ...
Run Code Online (Sandbox Code Playgroud)


Dav*_* W. 7

每当你有一个shell脚本,你需要调试,使用set -xv.这将打开详细模式,该模式将打印出执行的每一行,并将打开xtrace,这将在扩展完成时显示命令.

您可以关闭set -xv使用set +xv.您可以封装整个脚本,或仅包含导致您心痛的行.

如果你这样做了,我想你会看到它$video_title扩展到包含空格的名字,那就是你得到错误的时候.您应该在脚本中的任何地方放置引号,其中包含"$ video_title":

if [ -f "$video_title".$ext2 ]   #QUOTES!
then
    ffmpeg -i "$video_title".$ext2 "$video_title".wav  #EVEN MORE QUOTES
Run Code Online (Sandbox Code Playgroud)

请记住,这[实际上是一个命令,并且是命令的同义词test.您的if命令可以写成:

if test -f "$video_title".$ext2  #QUOTES!
then
Run Code Online (Sandbox Code Playgroud)

与所有命令一样,shell将分解您在空格上给命令的参数.因此,在传递给此命令之前,您的标题" 萝卜的生命 "将被分解为五个单独的参数"The","Life","of","a""Radish"test.

这解释了您的错误消息:

youtube2mp3.sh: line 31: [: too many arguments
Run Code Online (Sandbox Code Playgroud)

因为-f命令行参数只能接受一个附加参数而不是shell传递给它的五个参数.引号使shell不会将您的视频标题分解为-f标志的单独参数.

顺便说一下,打印出test($ man test)上的联机帮助页,你会发现它需要采取所有相同的参数[ ... ].它还解释了为什么[并且]需要被空格包围 - 这些是Unix命令,Unix命令必须用空格包围.

还运行此命令:

$ ls -il /bin/[ /bin/test
10958 -rwxr-xr-x  2 root  wheel  18576 May 28 22:27 /bin/[
10958 -rwxr-xr-x  2 root  wheel  18576 May 28 22:27 /bin/test
Run Code Online (Sandbox Code Playgroud)

第一个参数是inode.它有点像文件的真实名称(您认为文件名和目录是inode的属性).您将看到两者test[具有相同的inode编号,因此实际上是相同的文件(通过ln命令)链接到同一文件.

(不完全正确.这[是你可能正在使用的Korn和BASH的[内置命令.但是,内置命令内部链接到另一个被调用的内置命令test.)