6

我已修改此脚本以从 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
4

2 回答 2

8

始终引用参数扩展。的值$video_title被拆分为多个单词,这使[命令感到困惑。

if [ -f "$video_title.$ext1" ]
then
     ffmpeg -i "$video_title.$ext1" ...
于 2013-07-15T12:39:23.773 回答
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

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

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

像所有命令一样,shell 会将您提供给命令的参数分解为空格。因此,您的标题“ The Life of a Radish ”将被分解为五个单独的参数“The”“Life”“of”“a”“Radish” ,然后再传递给此test命令。

这解释了您的错误消息:

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

因为-f命令行参数只能带一个附加参数,而不是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 的内置命令。但是,[内置命令在内部链接到另一个调用的内置命令test。)

于 2013-07-15T14:15:51.807 回答