测试命令抱怨“参数太多”

时间:2014-07-18 02:13:32

标签: shell double-quotes

错误消息是此问题标题中的错误消息。 看起来问题出在[ ]内,但我不确定。

该程序的目的是获取两个参数(目录和扩展名)并删除该目录中具有该扩展名的所有文件:

count=0
for i in $1/*.$2 ; do
       if [ -s $i ]
                then rm $i
                echo "$i deleted"
        fi
done

1 个答案:

答案 0 :(得分:2)

@ lurker的评论提供了关键指针:需要双引号才能将$i等变量引用扩展为其值,而无需进一步解释。

[POSIX兼容,Bourne-like] shell编程的一些经验法则:

  • 始终双引号变量引用以防止shell对其值的解释(例如将值拆分为多个标记并将值解释为glob(文件名)图案));例如,诸如"$i"的变量引用。
    • 据推测,您的问题是$i的值包含空格,并且由于$i未加引号,因此shell会将值拆分为多个标记,从而产生语法错误,因为-s运算符只接受单个参数。
  • 相反,如果明确希望shell解释值仅使用未加引号的字符串和变量引用;例如,诸如*之类的glob中的*.txt,因为它是未加引号的,被视为通配符。
    • 请注意,您的glob $1/*.$2是有问题的,因为它仍然包含未加引号的变量引用 - 请参阅下一点。
 
  • 单个字符串可以(并且可能需要)混合两种方法
    • 引用您想要的部分UN解释( double - 包含变量引用和类似表达式的字符串,单个 - 引用字符串文字)。
    • LEAVE UNQUOTED你想要解释的部分,例如通配符的通配符(路径名扩展。
    • 因此,您的glob的健壮版本如下:"$1"/*."$2" - 变量引用双引号,但通配符(*)未引用。
      • (这也可以写成"$1/"*".$2",只留下未加引号的全局字符,但为了清楚起见,我选择单独引用参数引用;因为,/和{ {1}}不受shell的解释,任何一种形式都可以使用。)

如果我们把它们放在一起:

.