Bash编程:条件语句中的评估

时间:2014-08-29 09:58:21

标签: bash

在bash脚本中使用“&&”

时,if条件语句无法正常工作
ARGCOUNT=$#

if (( "$ARGCOUNT" != "2" )) ;then
  echo "number of arguments must be two"
fi

DFLAG=$1

HFLAG=$2
if (((( $DFLAG = "Mon" )) || (( $DFLAG = "MON" )) || (( $DFLAG = "mon" ))) && ((( HFLAG = "2" )) || (( HFLAG = "3" )) || (( HFLAG = "4" ))));then
  echo " CS599 "
  cd CS599
elif (((( $DFLAG = "Wed" )) || (( $DFLAG = "WED" )) || (( $DFLAG = "wed" ))) && ((( HFLAG = "2" )) || (( HFLAG = "3" )) || (( HFLAG = "4" ))));then
  cd CS699
  echo " CS699 "
elif (((( $DFLAG = "Fri" )) || (( $DFLAG = "FRI" )) || (( $DFLAG = "fri" ))) && ((( HFLAG = "2" )) || (( HFLAG = "3" )) || (( HFLAG = "4" ))));then
  cd CS799
  echo " CS799 "
else
  echo "."
fi

我的程序只执行else语句而不管参数如何。意味着它评估块是否错误。

有什么问题?

3 个答案:

答案 0 :(得分:2)

您使用的括号用于算术评估。我认为你已经过度使用它们,这会使你的脚本变得复杂。

下面的代码段确实有效:

#!/bin/bash
ARGCOUNT=$#

if [ "$ARGCOUNT" -ne 2 ] ;then echo "number of arguments must be two"; fi

# put DFLAG in lower case (see man bash).
DFLAG=${1,,}
HFLAG=$2

if [ "$DFLAG" = 'mon' -a "$HFLAG" -ge 2 -a "$HFLAG" -le 4 ]; then
  echo ok
else
  echo failed
fi

如您所见,我优化了您的表达式:

  • 除了$ARGCOUNT的情况(由于您将其初始化为$#而安全),不要忘记用双引号括起变量以避免扩展。
  • DFLAG的声明中,我使用转换为小写字符串运算符(?)。有了这个,你不必在DFLAG中检查每个案例的排列。这可能不适用于bash3。
  • 如果您使用内置的test[,则可以在每个表达式之间使用-a来执行and
  • 使用test / [内置函数进行算术运算时使用以下运算符:-ne(不等式), - eq(相等)-ge(大于或等于),{ {1}}(较小或等于), -lt (较小), - GB(较大)。
  • 正如另一个答案所说,你可以替换" $ DFLAG" =' mon' by" $ DFLAG" ==' mon'。但这并不符合POSIX(正如我在下面的评论中所述)而且我对此知之甚少并不知道它是否是个好主意。

另外,如果-le条件应始终相同,您可以像这样编写代码:

$HFLAG

如果是这种情况,我会在你使用bash3的情况下重新安排案例的所有排列,向你展示一个没有if [ "$HFLAG" -ge 2 -a "$HFLAG" -le 4 ]; then case "$DFLAG" in mon|Mon|MON) echo "monday"; ;; fry|Fry|FRY) echo "friday"; ;; *) echo "other" ;; esac fi 的例子。

答案 1 :(得分:0)

如果你正在寻找你做了哪些错误,哪个错误就要去其他地方...那么这是一个简单的错误,几乎每个程序员都会在生活中做过一次...使用单个" = "而不是" =="在比较期间。相应地进行修改,您应该在脚本中得到预期的流量/结果。

One eg.

$DFLAG = "Mon"

change to below notice the double equal sign 

"$DFLAG" == "Mon"

答案 2 :(得分:0)

首先,你应该在括号上轻松一点。那些都是脆弱的东西。

使用Bash语法(非POSIX,不太便携),您可以写:

ARGCOUNT=$#
DFLAG=${1,,} # lower case
HFLAG=$2

 # don't need the quotes in (( )) as we test arithmetic value
(( $ARGCOUNT != 2 )) && echo "number of arguments must be two"

shopt -s extglob # for @(1|2|3) below, see http://mywiki.wooledge.org/glob#extglob
if [[ $DFLAG = "mon" && $HFLAG == @(2|3|4) ]]; then
  echo " CS599 "
  cd CS599
if [[ $DFLAG = "wed" && $HFLAG == @(2|3|4) ]]; then
  cd CS699
  echo " CS699 "
if [[ $DFLAG = "fri" && $HFLAG == @(2|3|4) ]]; then
  cd CS799
  echo " CS799 "
else
  echo "."
fi

现在您可以看到自己重复了多少并且可以改进算法。例如,测试HFLAG,如果有效测试DFLAG则另外...

读取