如果条件出现括号,为什么没有空格时出现语法错误?


17

我使用下面的脚本将脚本从一年的开始两天开始运行时向后移动两天,并且还检查每个月的第一天和第二天并向后移动两天。

if [$month="01"] && [$day="01"];
then
    date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
if [$month="01"] && [$day="02"];
then
         date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
   if [ $day = "01" ];
then
    date="$last_month/$yes_day/$year"
            fulldate="$year$last_month$yes_day"
else
        if [ $day = "02" ];
then
    date="$last_month/$yes_day/$year"
        fulldate="$year$last_month$yes_day"
else
    date="$month/$yes_day/$year"
        fulldate="$year$month$yes_day"
                fi
               fi
              fi
fi

但我不好得到以下错误消息

Etime_script.sh: line 19: [06=01]: command not found
Etime_script.sh: line 24: [06=01]: command not found

1
给出的答案是正确的;之后需要空白[。此外,请查看该elif语句;它将帮助您清理东西。另外,if语句后的分号不是必需的,但也不是不正确的,只是很奇怪。
肖恩·高夫

@ ShawnJ.Goff如果将下一行(if [ ... ]; then)连接起来,则它们是必需的,因此并不稀奇。
goldilocks 2014年

@goldilocks,是的,这是我的首选样式。之所以与众不同,是因为他没有这样做。
肖恩·高夫

Answers:


27

[既不是元字符也不是控制运算符(甚至不是保留字;与相同]),因此它周围需要空格。否则,壳“看到”命令[01=01]而不是命令的[与独立的参数01=01,和]。每个运算符和操作数都必须是[命令的单独参数,因此运算符周围也必须有空格。

if [ "$month" = "01" ]

[$month="01"]是一个通配符模式匹配的任何字符$month"01。如果不匹配,则将其保留。

如果右括号后面有分号,则您不需要在其前面加上空格,因为分号始终是单独标记的一部分。

if [ "$month" = "01" ]; then

bash(以及ksh和zsh)双括号语法也是如此。

一个以上的条件

有两种组合条件的方法:

  1. [

  2. [结合使用&&或的单独命令||

在中用方括号分组可能更容易[

if [ "$month" = "01" -a "$day" = "01" ] # -a for and, -o for or

if [ "$month" = "01" ] && [ "$day" = "01" ]

应该避免使用第一个,因为它不可靠(例如,尝试使用month='!')。首先使用安全字符串(如果有)可以避免出现奇怪的变量内容问题。或使用[[/ ]]代替[/ ]

if [ "01" = "$month" -a "01" = "$day" ]

我们如何匹配if中的两个条件,例如if [$ month =“ 01”] && [$ day =“ 01”]; 我期望01 && 01 true,然后在以下条件下打印,或移至else语句
Kumar1 2014年

@AshokSanganahalli我扩大了答案。
Hauke Laging

1
[-a/ -o不使用/ 时,对于POSIX兼容的shell总是可靠的。使用-a/-oover 没有任何优势&&/||。我绝对不鼓励使用它。注意[[不是POSIX。
斯特凡Chazelas

4

另一种写法:

case $month:$day in
  (01:0[12])
    date="$last_month/$yes_day/$last_year"
    fulldate="$last_month/$yes_day/$last_year"
    ;;
  (*:0[12])
    date="$last_month/$yes_day/$year"
    fulldate="$year$last_month$yes_day"
    ;;
  (*)
    date="$month/$yes_day/$year"
    fulldate="$year$month$yes_day"
esac

1
+1 case表示。如果您有多个elif,则应该使用case
HalosGhost 2014年

-1

因此,这就是您的答案:

if [ $var1 == $var2 ];
 then
    echo "bla bla"
fi

因此,必须在方括号和变量/值之间放置“空格”。


不,我猜,因为当脚本在一年的开始两天运行时,我要求脚本向后移动两天,并且还要检查每月的第一天和第二天,然后向后移动两天就意味着[$ month =“ 01”] && [$ day =“ 01”]我们假设匹配条件为“ 01”和第一天“ 01”为true,则移动至随后或移动至其他条件
Kumar1 2014年

1
@AshokSanganahalli:我不知道这有什么关系,但是您的IF条件不起作用,因为您在方括号和值之间没有“空白”
2014年

@AshokSanganahalli对于具有您的技能水平的人来说,通常要对那些显然具有更好理解的人提出的更正提出异议,而至少不要尝试给出提示,这通常不是一个好主意。如果您的猜测是正确的,那么您不必在这里问,对吗?
Hauke Laging

4
-1用于未引用的变量,以及==代替standard的用法=
斯特凡Chazelas

2
该问题未标记为bash。标准[aka test命令中的相等比较运算符为=[如果要进行测试,则不会进行任何分配,因此无需消除歧义。一些[实现支持==作为对标准的扩展,但不是全部。Bourne shell的的,ash的,posh[S或在/bin/[某些系统的实例没有。==通过加入ksh,我想用于与在其新的相同运营商一致性(( ... ))构建体(其具有既=和==,但它没有标准)
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.