bash bash脚本中参数过多错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17653050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 05:55:02  来源:igfitidea点击:

Too many arguments error in bash script

bashshell

提问by frodo

I have modified this script to download songs from YouTube but I am getting the following error when I run it like this:

我已修改此脚本以从 YouTube 下载歌曲,但是当我像这样运行它时出现以下错误:

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

Errors:

错误:

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.

The line numbers are referring to the three if [ -f $video_title.$ext1 ]lines ... I thought I had the arguments ok as it worked in a previous version, but I'm stuck at this point — could someone explain what I need to do to correct it?

行号指的是if [ -f $video_title.$ext1 ]三行......我认为我的论点在以前的版本中没有问题,但我在这一点上被卡住了 - 有人可以解释我需要做什么来纠正它吗?

address=

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

回答by chepner

Always quote the parameter expansion. The value of $video_titleis being split into multiple words, which confuses the [command.

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

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

回答by David W.

Whenever you have a shell script you need to debug, use set -xv. This will turn on verbosemode which will print out each line executed, and will turn on xtracewhich will display the command when expansion is done.

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

You can turn off set -xvwith set +xv. You can envelope your entire script, or just the lines causing your heartaches.

您可以关闭set -xv使用set +xv。您可以包含整个脚本,或者只包含导致您心痛的行。

If you did this, I think you'll see that $video_titlegets expanded to names with spaces in them, and that's when you get your errors. You should be putting quotes everywhere in your script where you have `$video_title":

如果你这样做了,我想你会看到它$video_title被扩展为带有空格的名称,这就是你得到错误的时候。您应该在脚本中包含 `$video_title" 的任何地方加上引号:

if [ -f "$video_title".$ext2 ]   #QUOTES!
then
    ffmpeg -i "$video_title".$ext2 "$video_title".wav  #EVEN MORE QUOTES

Remember that [is actually a command and is a synonym to the testcommand. Your ifcommand could be written as:

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

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

Like all commands, the shell will break up the parameters you give to the command on white spaces. Thus, your title "The Life of a Radish" will get broken up as five separate parameters "The", "Life", "of", "a", and "Radish"before being passed to this testcommand.

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

This explains your error message:

这解释了您的错误消息:

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

Because the -fcommand line parameter can only take one additional parameter and not the five parameters the shell passed to it. The quotes keep the shell from breaking up your video title into separate parameters to the -fflag.

因为-f命令行参数只能带一个附加参数,而不能带外壳传递给它的五个参数。引号可防止 shell 将您的视频标题分解为单独的参数参数-f

By the way, print out the manpage on test($ man test) and you'll see that it takes all of the same parameters your [ ... ]take. It also explains why [and ]need to be surrounded by spaces -- these are Unix commands and Unix commands must be surrounded by white spaces.

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

Also run this command:

还运行此命令:

$ 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

That first parameter is the inode. It's sort of like the real name of the file (What you think is the file name and the directory are attributes of the inode). You will see that both testand [have the same inode number, and thus are really the same file that are linked (via the lncommand) to the same file.

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

(Not entirely true. The [is a builtin command to both Korn and BASH which you were probably using. However, the [builtin command is internally linked to another builtin command called testanyway.)

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