天天看点

Linux Shell编程之二选择结构

Shell编程学习之二

一、bash的条件测试

    测试方法或者说测试书写:

test EXPR

[ EXPR ]

` EXPR `

    例如:测试变量 User_Name 的之是否为root

    test $User_Name="root"

    [ $User_Name == "root" ]

    [[ $User_Name == "root" ]

    根据比较时操作数的类型,测试类型分为:

测试类型

运算符

运算符所代表的意义

示例

整形测试

-gt -lt -ge -le 

-eq -ne

-gt 大于  -lt 小于

-ge 大于或等于  -le 小于或等于

-eq 等于  -ne 不等于

都是双目运算符:

[ $num -gt 3 ]

test $num -ne $sum

[[ $num -ne 0 ]]

字符测试

== =~ > < !=

== 等于   >大于    < 小于

!= 不等于   =~ 模式匹配 

[ $num == "root"]

test $num > $sum

[[ "$num" =~ /bin/bash$ ]]

这里注意 =~只能用 ` `去匹配,而且=~后面的PATTERN(模式)不能使用"",''等引用字符

-n -z

-z 测试文件内容是否为空,为空时真,不为空为假

-n 测试文件内容是否为不空,不空为真,空为假

单目运算符

[ -n "$file_name" ]

文件测试

-a|e -f -L|h -d

-b -c -S -p -s

-r -w -x -N

-a|e 测试文件存在

-f 测试文件为一般文件

-L|h 测试文件为软连接文件

-d 测试文件是否为目录

-b -c -p -S 测试文件为块设备、字符设备、管道文件、socket文件

-r -w -x 测试文件可读、可写、可执行

-s 测试文件为空文件

-N 测试文件Mtime新于Atime

都是单目运算符

[ -f "$file_name" ]

[[ -b "$file_name" ]]

test -x $file_name

-nt -ot

file1 -nt file2 file1的Mtime新于file2的Mtime 

file1 -ot file2 file1的Mtime旧于file2的Mtime 

双目运算符

[ file1 -nt "$file_name" ]

[[ $file1 -ot "$file_name" ]]

二、逻辑运算

    布尔运算:布尔运算的结果只有2中:真和假。

    常见的逻辑运算有:与 或 非 异或。与或非常用 && || ! 来表示。

    与的逻辑关系:

假 && 任意

真 && 真

     或的逻辑关系:

真 || 任意

假 || 假

    非的逻辑关系:

!假

!真

    异或的逻辑关系:相同为假,不同为真

三、选择

    bash中的选择语句通常有if,case。当然if,case在大多数情况下是可以相互转换的。

1)if选择语句

1、单分支if语句:

    if CONDITION;then

选择分支

    fi

2、双分支的if语句:

选择分支1

    else

选择分支2

3、多分支的if语句:

    if CONDITION1;then

    elif CONDITION2;then

    elif CONDITION3;then

选择分支3

    ...

选择分支n

2)case语句

    语法格式:

        case 变量引用 in

        PATTERN1)

            分支1

            ;;

        PATTERN2)

            分支2

        ...

        *)

        分支n

        ;;

        esac

    PATTERN:类同于文件名通配机制,但支持使用“|”表示或者

    a|b: a或者b

    *:匹配任意长度的任意字符

    ?: 匹配任意单个字符

    []: 指定范围内的任意单个字符

4、练习

写一个脚本,完成如下任务,其使用形式如下所示:

    script.sh {start|stop|restart|status}

其中:

    如果参数为空,则显示帮助信息,并退出脚本;

    如果参数为start,则创建空文件/var/lock/subsys/script,并显示“starting script successfully.”

    如果参数为stop,则删除文件/var/lock/subsys/script,并显示“Stop script successfully.”

    如果参数为restart,则删除文件/var/locksubsys/script并重新创建,而后显示“Restarting script successfully.”

    如果参数为status,那么:

    如果文件/var/lock/subsys/script存在,则显示“Script is running...”,否则,则显示“Script is stopped.”

    说明:script.sh是脚本文件名,在创建时,其名称可以自己随意定义,但如果其名称发生变量,上/var/lock/sussys/下的文件名也要随之而变;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

<code>[root@server scripts]</code><code># cat myhttpd</code>

<code>#!/bin/bash</code>

<code>#</code>

<code># Description: </code>

<code># Version: 0.0.1</code>

<code># Author: Alex</code>

<code># Date: 2014-07-09</code>

<code>#判断参数个数,如果参数小于1,则提示用法并退出</code>

<code>if</code> <code>[ $</code><code># -lt 1 ];then</code>

<code>        </code><code>echo</code> <code>"Usage: `basename $0` {start|stop|restart|status}"</code>

<code>        </code><code>exit</code> <code>2</code>

<code>fi</code>

<code>#判断/var/lock/subsys是否存在,不存在则创建此目录</code>

<code>if</code> <code>[ ! -d </code><code>/var/lock/subsys</code> <code>];</code><code>then</code>

<code>    </code><code>/bin/mkdir</code> <code>-p </code><code>/var/lock/subsys</code>

<code>if</code> <code>[ </code><code>"$1"</code> <code>== </code><code>"start"</code> <code>];</code><code>then</code>

<code>#如果/var/lock/subsys/`basename $0`文件不存在,则创建,并显示启动成功;若存在则提示已启动</code>

<code>    </code><code>[ !  -e </code><code>"/var/lock/subsys/`basename $0`"</code> <code>] &amp;&amp; </code><code>/bin/touch</code>  <code>"/var/lock/subsys/`basename $0`"</code> <code>&amp;&amp; </code><code>echo</code> <code>"Starting `basename $0` successfully."</code> <code>\</code>

<code>    </code><code>||  </code><code>echo</code> <code>"`basename $0` is already start."</code>

<code>elif</code> <code>[ </code><code>"$1"</code> <code>== </code><code>"stop"</code> <code>];</code><code>then</code>

<code>#如果/var/lock/subsys/`basename $0`文件存在,则删除,并显示关闭成功;若不存在则显示关闭失败</code>

<code>    </code><code>[ -e </code><code>"/var/lock/subsys/`basename $0`"</code> <code>] &amp;&amp; </code><code>/bin/rm</code> <code>-f  </code><code>"/var/lock/subsys/`basename $0`"</code> <code>&amp;&amp; </code><code>echo</code>  <code>"Stop myhttpd successfully."</code> <code>\</code>

<code>    </code><code>|| </code><code>echo</code> <code>-e </code><code>"Stopping myhttpd \033[31mFAILED\033[0m."</code>

<code>elif</code> <code>[ </code><code>"$1"</code> <code>== </code><code>"status"</code> <code>];</code><code>then</code>

<code>#如果/var/lock/subsys/`basename $0`文件存在,显示running;若不存在则提示stopd</code>

<code>    </code><code>[ -e </code><code>"/var/lock/subsys/`basename $0`"</code> <code>] &amp;&amp; </code><code>echo</code> <code>"`basename $0` is running..."</code> <code>|| </code><code>echo</code> <code>"`basename $0` is stopped."</code>

<code>else</code>

<code>    </code><code>echo</code> <code>"Usage: `basename $0` {start|stop|restart|status}"</code>

    上面的脚本也可以用case语句结合函数来实现。

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

<code># 一般情况下,case与函数一起使用的居多。</code>

<code>[ $UID -</code><code>ne</code> <code>0 ] &amp;&amp; </code><code>echo</code> <code>"permission denied."</code> <code>&amp;&amp; </code><code>exit</code> <code>5</code>

<code>service_name=`</code><code>basename</code> <code>$0`</code>

<code>ser_path=</code><code>"/var/lock/subsys/$service_name"</code>

<code>start() {</code>

<code>    </code><code>if</code> <code>[ !  -e </code><code>"$ser_path"</code> <code>];</code><code>then</code>

<code>       </code><code>/bin/touch</code>  <code>"$ser_path"</code> 

<code>        </code><code>echo</code> <code>"Starting $service_name successfully."</code>

<code>    </code><code>else</code> 

<code>        </code><code>echo</code> <code>"$service_name is already start."</code>

<code>    </code><code>fi</code> 

<code>}</code>

<code>stop() {</code>

<code>    </code><code>if</code> <code>[ -e </code><code>"$ser_path"</code> <code>];</code><code>then</code>

<code>        </code><code>/bin/rm</code> <code>-f  </code><code>"$ser_path"</code>

<code>        </code><code>echo</code>  <code>"Stop $service_name successfully."</code>

<code>    </code><code>else</code>

<code>        </code><code>echo</code> <code>-e </code><code>"Stopping $service_name \033[31mFAILED\033[0m."</code>

<code>    </code><code>fi</code>

<code>status() {</code>

<code>        </code><code>echo</code> <code>"$service_name is running..."</code>

<code>        </code><code>echo</code> <code>"$service_name is stopped."</code>

<code>other() {</code>

<code>    </code><code>echo</code> <code>"Usage: $service_name {start|stop|restart|status}"</code>

<code>    </code><code>exit</code> <code>4</code>

<code>case</code> <code>"$1"</code> <code>in</code>

<code>  </code><code>start)</code>

<code>    </code><code>start</code>

<code>    </code><code>;;</code>

<code>  </code><code>stop)</code>

<code>    </code><code>stop</code>

<code>  </code><code>status)</code>

<code>    </code><code>status</code>

<code>  </code><code>*)</code>

<code>    </code><code>other</code>

<code>esac</code>

四、其他

1、组合条件测试:在多个条件间实现逻辑运算

    与:[ condition1 -a condition2 ]

    condition1 &amp;&amp; condition2

    或:[ condition1 -o condition2 ]

    condition1 || condition2

    非:[ -not condition ]

    ! condition

2、bash编程之交互编程

    read 与用户交互进行 

        -p "prompt" 提示语句

        -t timeout 设置超时时间

3、exit

    程序退出语句,一般是 exit n 这样使用,n是错误状态值。

4、shift

    通常是shift n 这样使用,n是要踢掉的参数个数

<code>[root@server scripts]</code><code># cat ./aboutshift </code>

<code>echo</code> <code>$1</code>

<code>shift</code> <code>2 </code><code>#踢掉2个参数</code>

<code>shift</code> <code>3 </code><code>#踢掉3个参数</code>

<code>[root@server scripts]</code><code># ./aboutshift 1 2 3 4 5 6 7 8 9 10</code>

<code>1</code>

<code>3</code>

<code>6</code>

    而shift真正的作用是,判断脚本参数的问题。例如:

写一个脚本,使用形式如下所示

    showifinfo.sh [-i INTERFACE|-a] [-v]

要求:

    1、-i或-a不可同时使用,-i用于指定特定网卡接口,-a用于指定所有接口;

        显示接口的ip地址

    2、使用-v,则表示显示详细信息

        显示接口的ip地址、子网掩码、广播地址;

    3、默认表示仅使用-a选项;

<code># 通过这种方法来判断一个脚本的参数选项</code>

<code>verbose=0</code>

<code>allInterface=0</code>

<code>ifflag=0</code>

<code>while</code> <code>[ $</code><code># -ge 1 ]; do</code>

<code>    </code><code>case</code> <code>$1 </code><code>in</code>

<code>    </code><code>-a)</code>

<code>    </code><code>allInterface=1</code>

<code>        </code><code>shift</code> <code>1</code>

<code>     </code><code>-i)</code>

<code>    </code><code>ifflag=1</code>

<code>    </code><code>interface=</code><code>"$2"</code>

<code>   </code><code>shift</code> <code>2</code>

<code>     </code><code>-</code><code>v</code><code>)</code>

<code>    </code><code>verbose=1</code>

<code>    </code><code>shift</code>

<code>     </code><code>*)</code>

<code>    </code><code>echo</code> <code>"wrong option"</code>

<code>    </code><code>exit</code> <code>2</code>

<code>     </code><code>esac</code>

<code>done</code>

<code>[ $ifflag -</code><code>eq</code> <code>1 -a $allInterface -</code><code>eq</code> <code>1 ] &amp;&amp; </code><code>"Usage Error."</code> <code>&amp;&amp; </code><code>exit</code> <code>12</code>

<code>    </code> 

<code>if</code> <code>[ $allInterface -</code><code>eq</code> <code>1 || $</code><code># -eq 0 ]; then</code>

<code>    </code><code>if</code> <code>[ $verbose -</code><code>eq</code> <code>1 ]; </code><code>then</code>

<code>    </code><code>ifconfig</code> <code>| </code><code>grep</code> <code>"inet addr:"</code>

<code>    </code><code>ifconfig</code> <code>| </code><code>grep</code> <code>"inet addr:"</code> <code>| </code><code>awk</code> <code>'{print $2}'</code> 

<code>if</code> <code>[ $ifflag -</code><code>eq</code> <code>1 ]; </code><code>then</code>

<code>    </code><code>ifconfig</code> <code>$interface | </code><code>grep</code> <code>"inet addr:"</code>

<code>    </code><code>ifconfig</code> <code>$interface | </code><code>grep</code> <code>"inet addr:"</code> <code>| </code><code>awk</code> <code>'{print $2}'</code> 

<code>fi</code>     

本文转自 羊木狼 51CTO博客,原文链接:http://blog.51cto.com/guoting/1436505,如需转载请自行联系原作者

下一篇: 考核总结

继续阅读