我已修改此脚本以从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
答案 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的内置命令无论如何。)