bash脚本中的参数错误太多

时间:2013-07-15 11:20:17

标签: bash shell

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

sh youtube2mp3.sh https://www.youtube.com/watch?v=gpOJ6iu8fqQ

错误:

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.

行号指的是三条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

2 个答案:

答案 0 :(得分:8)

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

if [ -f "$video_title.$ext1" ]
then
     ffmpeg -i "$video_title.$ext1" ...

答案 1 :(得分:6)

每当您需要调试shell脚本时,请使用set -xv。这将打开 verbose 模式,该模式将打印出执行的每一行,并将打开 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

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

if test -f "$video_title".$ext2  #QUOTES!
then

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

这解释了您的错误消息:

youtube2mp3.sh: line 31: [: too many arguments

因为-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

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

(不完全正确。[是您可能正在使用的Korn和BASH的内置命令。但是,[内置命令在内部链接到另一个名为{{1的内置命令无论如何。)