Shell 条件判断

if

语法

if test-commands; then
  consequent-commands;
[elif more-test-commands; then
  more-consequents;]
[else alternate-consequents;]
fi

test-commands 详细请查看测试

示例

检查脚本参数个数 > 3

if [ $# -lt 3 ]; then
    printf "%b" "Error. Not enough arguments.\n"
    printf "%b" "usage: myscript file1 op file2\n"
    exit 1
fi

if (( $# < 3 )); then
    printf "%b" "Error. Not enough arguments.\n"
    printf "%b" "usage: myscript file1 op file2\n"
    exit 1
fi

if (( $# < 3 )) 又是什么意思?

双括号是复合命令的一种。因为它会对其中的算术表达式求值,所以能在 if 语句中派上用场。这是一处比较新的 bash改进 2,专门用于有 if 语句的场合。

if [[ $FN == *.gif ]]
then
    gif2png $FN
elif [[ $FN == *.png ]]
then
    pngOK $FN
elif [[ $FN == *.jpg ]]
then
    jpg2gif $FN
elif [[ $FN == *.tif || $FN == *.TIFF ]]
then
    tif2jpg $FN
else
    printf "File not supported: %s" $FN
fi

正则匹配

#
for CDTRACK in *
do
    if [[ "$CDTRACK" =~ "([[:alpha:][:blank:]]*)- ([[:digit:]]*) - (.*)$" ]]
    then
        echo Track ${BASH_REMATCH[2]} is ${BASH_REMATCH[3]}
        mv "$CDTRACK" "Track${BASH_REMATCH[2]}"
    fi
done

case

语法

case word in
    [ [(] pattern [| pattern]) command-list ;;]...
esac

case 语句会扩展 casein 之间的单词(包括参数替换)。

然后依次尝试匹配各个模式。这可是 shell 了不得的一项特性。它不是简单地比对值,而是进行字符串模式匹配

匹配过程区分大小写,但可以用 shopt -s nocasematch(bash 3.1 以上版本可用)改变此行为。

示例

# 匹配变量相等
case "a" in
  a | b) echo 1;;
  c) echo 2;;
  *) echo 3;;
esac

# 模式匹配
case $FN in
    *.gif) gif2png $FN
        ;;
    *.png) pngOK $FN
        ;;
    *.jpg) jpg2gif $FN
        ;;
    *.tif | *.TIFF) tif2jpg $FN
        ;;
    *) printf "File not supported: %s" $FN
        ;;
esac
  • ;;

用于结束与某个模式关联的一组语句。从 bash 4 开始,还可以用另外两种写法结束一组语句。

  • ;;& 表示,即便找到匹配,依然尝试匹配下一个模式,如果发现该模式也匹配,则执行与之关联的语句。

  • ;& 表示执行流程会“直落而下”,不管模式是否匹配,都执行下一组语句。

# 使用其他结束标记

case $FN in
    *.gif) gif2png $FN
            ;;&         # 继续向下查找匹配
    *.png) pngOK $FN
            ;;&         # 继续向下查找匹配
    *.jpg) jpg2gif $FN
            ;;&         # 继续向下查找匹配
    *.tif) tif2jpg $FN
            ;&          # 直落而下
    *.* ) echo "two.words"
            ;;
    * ) echo "oneword"
esac