7

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

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?

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
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
frodo
  • 1,053
  • 5
  • 17
  • 33
  • 6
    Try double quoting the variable names in the test command. e.g. `if [ -f "$video_title.$ext1" ]` etc – user000001 Jul 15 '13 at 11:24
  • 1
    you run it in `sh` instead of `bash`. try to change that and report back. also put `""` around your url and report back with that. – mnagel Jul 15 '13 at 11:29
  • This is basically a duplicate of https://stackoverflow.com/questions/10067266/when-to-wrap-quotes-around-a-shell-variable – tripleee Jun 22 '17 at 03:37

2 Answers2

10

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

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

If you did this, I think you'll see that $video_title gets 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":

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 test command. Your if command could be written as:

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 test command.

This explains your error message:

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

Because the -f command 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 -f flag.

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.

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 test and [ have the same inode number, and thus are really the same file that are linked (via the ln command) to the same file.

(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 test anyway.)

David W.
  • 105,218
  • 39
  • 216
  • 337
8

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

if [ -f "$video_title.$ext1" ]
then
     ffmpeg -i "$video_title.$ext1" ...
chepner
  • 497,756
  • 71
  • 530
  • 681