Bash编程(2) 循环与分支

Shell中有三种类型的循环:for, until, while,具有3种类型的条件语句:if, case, 条件操作符(&&, ||)。

1. 结束码

命令的结束码可以在命令运行完后,查看$?查看。当命令执行正常时,结束码为0,当异常时,返回1-255的数字。

$ printf "%v\n"
-bash: printf: `v': invalid format character
$ echo $?
1

$ mkdir /qwerty
mkdir: cannot create directory `/qwerty': Permission denied
$ echo $?
1 

2. test命令

test命令用于计算多种表达式,包括文件属性,整型,字符串等。与test对应的,常见有两种符号:[[和((。其中((用于测试数值表达式,[[ ... ]]用于测试正则表达式。具体可以查看man test。

注意:[ test和[test是2个概念,bash对于空格比较敏感。

(1) 文件测试

a. -e: 表示文件是否存在

b. -f: 检查文件是否存在并且是否为普通文件

c. -d: 检查是否为文件夹

-h, -L: 是否为符号链接

$ test -f /etc/fstab # 当为普通文件时为true
$ echo $?
0

$ test -h /etc/rc.local # 当为软连接时为true
$ [ -x "$HOME/bin/hw" ] # 当指定文件可执行时为true
$ [[ -s $HOME/bin/hw ]] # 当文件存在且非空时为true 

(2) 整型测试

整型比较常见符号有-eq, -ne, -gt, -lt, -le

$ test 1 -eq 1 # 测试是否相等
$ echo $?
0
$ [ 2 -eq 1 ]
$ echo $?
1
$ [ 2 -ne 1 ] # 测试不等
$ echo $?
0 

(3) 字符串测试

a. =:字符串相等,等同于" == ",例:test "$a" = "$b"

b. != : 字符串不相等,例:[ "$q" != "$b" ]

c. -z : 字符串是否为空,例:[ -z "" ]

d. -n : 字符串是否非空,例:test -n ""

e. 字符串比较大小,注意 >, <防止被解释为重定向。例:

$ str1=abc
$ str2=def
$ test "$str1" \< "$str2"
$ echo $?
0
$ test "$str1" \> "$str2"
$ echo $?
1 

f. -a : 逻辑与,等同于" && ",例:test -f /path/to/file -a $test -eq 1

g. -o : 逻辑或,等同于" || ",例:test -x bin/file -o $test -gt 1

3. [[ ... ]] : 计算一个表达式

如:[[ -f music_job.zip && 1 -eq 1 ]]

[[ ... ]]有个特征,即通过使用=~操作符来匹配正则表达式。

$ [[ $string =~ h[aeiou] ]]
$ echo $?
0
$ [[ $string =~ h[sdfghjkl] ]]
$ echo $?
1 

4. (( ... )):计算算术表达式

((  算数表达式 )),当其中的算术表达式计算为0时,返回false,否则为true。例:

$ test $(( a - 2 )) -ne 0
$ [ $a != 0

由于(( ... ))是shell语法而非内置命令,因此 >, <符号将不会被当做重定向符。

例a:if (( total > max )); then: ...; fi

例b: (( verbose )) && command ## 当verbose != 0时,执行command命令

在(( ... ))中如果存在非数值,则默认结果为0,例:

$ y=yes
$ ((y)) && echo $y || echo n
n 

注意:当(( ... ))中的变量代表数字时,可省略$符号

5. 条件执行

(1) if

格式为:

if <condition list>
then
    <list>
fi 

示例:

example 1:
read name
if [[ -z $name ]];then
    echo "No name enterd" >&2
    exit 1
fi 

example 2:
printf "Enter a number not greater than 10: "
read number
if (( number > 10 ));then
    printf "%d is too big\n" "$number" >&2
    exit 1
else 
    printf "You entered %d\n" "$number"
fi

example 3:
printf "Enter a number between 10 and 20 inclusive: "
read number
if (( number < 10 )); then
    printf "%d is too low\n" "$number" >&2
    exit 1
elif (( number > 20 ));then
    printf "%d is too high\n" "$number| >&2
    exit 1
else 
    printf "You entered %d\n" "$number"
fi 

 (2) 条件操作符&&, ||

包含&&, ||条件运算符的列表将从左向右依次执行。只有&&前的命令执行成功,才会执行&&后的命令;只有||前的命令执行失败,才会执行||后的命令。

例a:test -d "$director" && cd "$director" ## 检测目录存在,才会进入

例b: cd "$HOME/bin" || exit 1 ## 进入bin目录失败时,将会退出

例c: mkdir "$HOME/bin" && cd "$HOME/bin" || exit 1 ## 创建bin目录失败或进入bin目录失败,将退出

例:

if [ -d "$dir" ] && cd "$dir";then
    echo "$PWD"
fi 

(3) case

格式为:

case WORD in
    PATTERN) COMMANDS ;;
    PATTERN) COMMANDS ;; 
esac 

例:case用于检测字符串是否包含:

case $1 in
    *"$2"*) echo "true" ;;
    *) echo "false" ;;
esac 

例:case用于判断数值是否有效

case $1 in
    *[!0-9]*) false ;;
    *) true ;;
esac 

例:判断参数的个数

case $# in
   3) ;; ## We need 3 args, so do nothing
   *) printf "%s\n" "Please provide three names" >&2
      exit 1
      ;;
esac 

6. 循环

(1) while

格式为:

while <list>
do 
    <list>
done 

例:累加

n=1
while [ $n -le 10]
do 
    n=$(( $n + 1 ))
done 

例:true条件则无限循环

while true
do
    read x
done 

例:从文件中逐行读取

while IFS= read -r line
do
    : do something with "$line"
done < FILENAME? 

(2) until

until与while相反,当循环条件失败时结束。例:

n=1
until [ $n -gt 10 ]
do
    echo "$n"
    n=$(( $n + 1 ))
done 

(3) for

for var in Canada USA Mexico
do
    printf "%s\n" "$var"
done 

 另一种格式:

for (( n=1; n<=10; ++n))
do
    echo "$n"
done 

 (4) break

while :
do
    read x
    [ -z "$x" ] && break   #输入为空字符串时,退出
done 

 break后如果带有数值,则表示可以跳出多次嵌套的循环:

for n in a b c d e
do
    while true
    do
        if [ $RANDOM -gt 20000 ];then
            printf .
            break 2 # 跳出while以及for循环
        elif [ $RANDOM -lt 10000 ];then
            printf '"'
            break    ## 仅跳出while循环
        fi
    done
done
echo 

 (5) continue

for n in {1..9}
do
    x=$RANDOM
    [ $x -le 20000 ] && continue
    echo "n=$n x=$x"
done

 

猜你喜欢

转载自www.cnblogs.com/mengrennwpu/p/10179689.html
今日推荐