if 条件中的括号:为什么我会收到没有空格的语法错误?

Kum*_*ar1 18 shell bash shell-script whitespace test

当脚本在一年的开始两天运行时,我使用下面的脚本将两天后移,并检查每个月的第一天和第二天,然后将后移两天。

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
Run Code Online (Sandbox Code Playgroud)

但我的坏消息是收到以下错误消息

Etime_script.sh: line 19: [06=01]: command not found
Etime_script.sh: line 24: [06=01]: command not found
Run Code Online (Sandbox Code Playgroud)

Hau*_*ing 28

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

if [ "$month" = "01" ]
Run Code Online (Sandbox Code Playgroud)

[$month="01"]是一个通配符模式匹配的任何字符$month"01。如果它不匹配任何东西,它就会被单独留下。

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

if [ "$month" = "01" ]; then
Run Code Online (Sandbox Code Playgroud)

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

不止一个条件

条件组合有两种方式:

  1. 之内 [

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

用括号分组可能更容易[

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

if [ "$month" = "01" ] && [ "$day" = "01" ]
Run Code Online (Sandbox Code Playgroud)

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

if [ "01" = "$month" -a "01" = "$day" ]
Run Code Online (Sandbox Code Playgroud)


Sté*_*las 5

另一种写法:

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
Run Code Online (Sandbox Code Playgroud)