Chinaunix首页 | 论坛 | 博客
  • 博客访问: 388791
  • 博文数量: 166
  • 博客积分: 1972
  • 博客等级: 上尉
  • 技术积分: 1845
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-19 21:16
文章分类

全部博文(166)

文章存档

2013年(7)

2010年(159)

分类:

2010-10-19 18:21:23

103流程控制结构

v      控制结构一般有三种:

   顺序结构;

   分支结构;

   循环结构。

1031       顺序结构

v      顺序结构是程序中最简单的控制结构,从脚本的开始到结束,按照顺序执行每一条语句。

v      请看以下示例:

v      顺序结构示例:读用户输入的姓名并显示。

[root@server root]#cat  e7.sh

#!/bin/sh

echo "Hello !"

echo -n "What's your name: "

read yourname

echo "Hello $yourname !"

exit 0

[root@server root]# ./e7.sh

Hello !

What's your name: Tom

Hello Tom !

v      查看本示例的退出状态如下:

[root@server root]#echo $?

0

1032       条件测试

v      shell中提供了test命令来实现上述的条件测试功能。

v      shell脚本中条件测试既可以用在分支结构中,又可以用在循环结构中。

1test命令

1test命令有两种使用格式:

第一种是在test语句后加上测试条件;

第二种是用方括号代替test

2test命令的格式如下:

test 测试条件

[ 测试条件 ]

2.文件测试

v      文件测试条件示例:

[root@server myshell]# test  –f  e2.sh

[root@server myshell]# echo $?

0

功能:测试文件e2.sh是否为普通文件,测试结果为e2.sh是普通文件。

 

[root@server myshell]# [ -f  e60.sh ]

[root@server myshell]# echo $?

1

要求:测试文件le2.sh是否为符号连接文件

[root@server myshell]# ln -s  e2.sh  le2.sh

[root@server myshell]# [ -L  le2.sh ]

[root@server myshell]# echo $?

0

v      要求:测试文件/dev/hda1是否是块设备文件。

[root@server myshell]# [ -b  /dev/hda1 ]

[root@server myshell]# echo $?

0

更多文件测试请参见P61

3.字符串测试

3.字符串测试

v      字符串测试示例:

[root@server root]#echo $LOGNAME

root

[root@server root]#[ $LOGNAME  = root ]

[root@server root]#echo $?

0

4.数值测试

v      expr1 eq expr2

功能:当表达式expr1的值与表达式expr2的值相等

v      expr1 ne expr2

功能:当表达式expr1的值与表达式expr2的值不相等

v      expr1 gt expr2

功能:当表达式expr1的值大于与表达式expr2的值

v      expr1 lt expr2

功能:当表达式expr1的值小于与表达式expr2的值

v      expr1 ge expr2

功能:当表达式expr1的值大于等于表达式expr2的值

v      expr1 le expr2

功能:当表达式expr1的值小于等于表达式expr2的值

数值测试示例:

[root@ server root]# a=10

[root@ server root]# b=20

[root@ server root]# declare  -i  c

[root@ server root]# c=$a+$b

[root@ server root]# echo $c

30

[root@ server root]# [ $c -eq 30 ]

[root@ server root]# echo $?

0

[root@ server root]# [ $c -eq "30" ]

[root@ server root]# echo $?

0

[root@ server root]# [ $c -ne 30 ]

[root@ server root]# echo $?

1

[root@ server root]# [ $c -ge 35 ]

[root@ server root]# echo $?

1

5.逻辑操作符

v      shell提供的逻辑操作符有三个:

   一是逻辑与、

   二是逻辑或、

   三是逻辑非。

v      逻辑与操作符示例:

[root@ server root]# name=Tom

[root@ server root]# password=abc

[root@ server root]# [ $name = Tom a $password = abc ]

[root@ server root]# echo $?

0

功能:测试变量$name是否等于“Tom”并且$password是否等于“abc”

示例:

[root@ server root]# ls l  e3.sh

-rw-r--r--  1 root root  41  Jan 14 12:16 e3.sh

[root@ server root]# [ -r  e3.sh  -a  -x  e3.sh ]

[root@ server root]#l echo $?

1

功能测试文件e3.sh是否同时具有读权限和可执行权限。

逻辑或操作符示例

[root@ server root]# name=Tom

[root@ server root]# password=abc

[root@ server root]# [ $name = Tom -o  $password = 123456]

[root@ server root]# echo $?

0

v      逻辑非操作符示例:

[root@ server root]# ls l e3.sh

-rw-r--r--  1 root root  41  Jan 14 12:16 e3.sh

[root@ server root]# [ -x  e3.sh ]

[root@ server root]# echo $?

1

[root@ server root]# [ ! –x  e3.sh ]

[root@ server root]# echo $?

0

需要注意的是,逻辑非的两边也必须各有一个空格。

1033       分支结构

v      shell中有两种形式的分支结构:

   一种是if分支结构,

   另一种case分支结构。

1if分支结构

v      if分支结构的基本格式如下:

if 条件测试1; then

条件测试1为真时的语句序列

[elif条件测试2; then]

条件测试2为真时的语句序列

...

[else]

条件测试为假时的语句序列

fi

v      if分支结构示例一:用户输入字符串,判断其内容是否与存储在变量$name中的内容相同。

[root@server root]# cat  e10.sh

#!/bin/sh

name="garfield"

echo -n "Please input:"         

read uservalue

if [ $uservalue = $name ]; then

       echo "same"

else

       echo "difference"

fi

执行:

[root@server root]# ./e10.sh

Please input:abc

difference

[root@server root]# ./e10.sh

Please input:garfield

same

v      if分支结构示例二:判断今天是不是星期一。

[root@server root]# cat  e12.sh

#!/bin/sh

today=`date +%u`

if [ $today = 1 ]; then

       echo "Today is Monday"

else

       echo " Today is not Monday "

fi

v      执行:

[root@server root]# date

Sun Jan 14 17:12:25 CST 2007

[root@server root]# ./e12.sh

Today is not Monday

v      if分支结构示例三:判断用户指定文件的类型。

[root@server root]# cat  e13.sh

#!/bin/sh

usefile=$1

if [ -d $usefile ]; then

       echo "directory"

elif [ -f $usefile ]; then

       echo "normal"

elif [ -b $usefile ]; then

       echo "block device"

elif [ -c $usefile ]; then

       echo "char device"

else

       echo "other"

fi

执行

[root@server root]# ./e13.sh  e13.sh

normal

2case分支结构

case语句的结构如下

case  in

       模式1)

              语句组1

              … …

              ;;

       模式2

              语句组2

              ……

              ;;

       ……

       *

              语句组n

esac

case分支结构示例一:通过判断$1的值,设置用户指定文件的权限。

[root@server root]# cat e16.sh

#!/bin/sh

option=$1

filename=$2

case $option in

       r)

              chmod u+r $filename

              ;;

       w)

              chmod u+w $filename

              ;;

       x)

              chmod u+x $filename

              ;;

       *)

              echo "error!"

              exit 1

              ;;

esac

exit 0

[root@server root]# ls  -l  abc

-rw-r--r--  1 root root 161  Jan 13  21:36 abc

[root@server root]# ./e16.sh  x  abc

[root@server root]# ls  -l  abc

-rwxr--r--  1 root root 161  Jan 13  21:36 abc

v      case分支结构示例二:提示键入“y”“n”,根据实际输入执行相应分支。

#!/bin/sh

echo -n "Please input your choice [y|n]:"

read ch

case $ch in

       y|Y|yes||YES)

              echo " go on "

              ;;

       n|N|no|NO)

              echo "cancel"

              ;;

       *)

              echo "error ,you should input[y|n]"

              exit 1

              ;;

esac

exit 0

v      执行:

[root@server root]# ./e17.sh

Please input your choice [y|n]:y

go on

1034       循环结构

1for循环

其典型格式如下:

for  变量  in  12 …n

do

    语句1

    语句2

    ……

done

for循环示例一:显示全部位置变量参数。

[root@server root]# cat  e19.sh

#!/bin/sh

for  i  in  $@   

do

       echo $i

done

[root@server root]#./e19.sh a b c "d  e"

a

b

c

d  e

说明如果省略了in则默认从$*$@中取值。

for循环示例二:显示$PATH变量中各目录的名称。

[root@server root]# cat  e20.sh

#!/bin/sh

IFS=:

for dir in $PATH

do

   ls -ld $dir

done

echo "Finished!"

v      执行:

[root@server root]#./e20.sh

drwxr-xr-x    2 root     root         4096 Feb  7  1996 /usr/local/bin

drwxr-xr-x    2 root     root         4096 Feb 18  2003 /bin

drwxr-xr-x    2 root     root        36864 Aug 24 22:00 /usr/bin

drwxr-xr-x    2 root     root         4096 Feb 18  2003 /usr/X11R6/bin

Finished!

for循环示例三:C语言相似的格式用法。

[root@server root]#cat ./e21.sh

#!/bin/sh

for ((i=1;i<=6;i++))

do

  for((j=1;j<=i;j++))

  do

    echo -e "*\c"

  done

    echo

done

[root@server root]# ./e21.sh

*

**

***

****

*****

******

2while循环

while循环的格式如下:

while 条件

do

       语句1

       语句2

       ……

done

v      while循环示例:逐行显示一个文本文件的内容,忽略以符号“#”开头的行,并在所显示的每一行前加上行号。

[root@server root]# cat  e23.sh

#!/bin/sh

counter=1

while read line

do

       if ! [ ${line:0:1} = "#" ]; then

              echo "$counter: $line"

              counter=$[counter+1]

       fi

done < $1

[root@server root]# ./e23.sh  e23.sh

1: counter=1

2: while read line

3: do

4: if ! [ ${line:0:1} = "#" ]; then

5: echo "$counter: $line"

6: counter=$[counter+1]

7: fi

8: done < $1

3select循环

格式如下:

select name [ in list ]

do

 语句列表

done

select提供了一个菜单循环选项,供用户选择,并有以下特点:

1)其中list中的每一项都对应一个数字,用户键入的值会被存到变量REPLY

2select用到了PS3提示符 ,默认值为#?,用户可以更改。

3select是无限循环,所以应在循环体内提供退出循环的语句

[root@server root]# cat  e24.sh

#!/bin/sh

select  myoption  in  shopping fishing cooking quitting

do

  case  $myoption  in

    shop*) echo I want to go $myoption with lots of money.

           ;;

    fish*) echo I want to go $myoption with John.

          ;;

    cooking) echo I am cooking a small fish.

          ;;

    quit*) echo bye.

           break

          ;;

    *)   echo try again!

         ;;

    esac

done

echo "Finished!"

v      执行:

[root@server root]#./e24.sh

1) shopping

2) fishing

3) cooking

4) quitting

#? 2

I want to go fishing with John.

#? 3

I am cooking a small fish.

#? 4

bye.

Finished!

34       shell函数

341 函数的定义

shell中定义函数有两种格式:

function funcname

{

   shell commands

}

funcname()

{

   shell commands

}

定义函数示例:定义一个shell函数。

[root@server root]# cat e29.sh

#!/bin/sh

myfunction()

{

       echo "Hello,world!"

}

1042       函数的调用与执行

v      调用shell函数示例:利用select循环、case语句调用定义好的函数。

[root@server myshell]# cat e25.sh

#!/bin/sh

ps_fun()

{

 ps aux

}

function log_fun

{

 tail /var/log/messages

}

ls_fun()

{

  ls -la

}

select myaction in display_proc show_log list_dir quit

do

  case $myaction in

     display_proc)

                  ps_fun ;;

         show_log)

                  log_fun ;;

         list_dir)

                  ls_fun ;;

             quit)

                  break ;;

                *)

                  echo error ;;

  esac

done

v      执行:

[root@server myshell]# ./e25.sh

1) display_proc

2) show_log

3) list_dir

4) quit

#? 3

total 40

drwxr-xr-x   2 root root 4096 Jan 14 19:38 .

drwxr-x---  24 root root 4096 Jan 14 19:38 ..

-rwxr-xr-x   1 root root   36 Jan 14 18:02 e19.sh

-rwxr-xr-x   1 root root  101 Jan 14 18:19 e21.sh

1043       参数的传递

v      函数的参数与脚本的参数非常相似,也是使用$1$2……,以及$#等特殊变量。

v      请看如下示例。

v      参数的传递示例:由用户控制循环的次数。

[root@server myshell]# cat  ./e26.sh

#!/bin/sh

my_fun()

{

  over=$1

  counter=1

  while [ $counter -le $over ]

  do

    echo $counter

    counter=$[counter+1]

  done

}

echo -n "Please input a number:"

read num

my_fun $num

v      执行:

[root@server myshell]# ./e26.sh

Please input a number:5

1

2

3

4

5

1044       函数的返回

在函数中使用return语句,可以完成这个功能,其语法如下:

return          

   从函数中返回, 上一条语句的执行状态决定返回值。

return  0

返回值为0,一般表示无错误返回。

return  1    

返回值为1,一般表示有错误返回。

105本章小结

v      bash脚本编程的基本概念

v      语句、流程控制

v      环境变量、引用、变量替换、条件测试、分支、循环结构

 

#! /bin/sh

is_directory()

{       

DIR_NAME=$1

if [ ! -d $DIR_NAME ]; then

return 0

else

return 1

fi

}

for DIR in "$@"

do

if is_directory "$DIR"

then

echo "$DIR doesn't exist. Creating it now..."

mkdir $DIR

if [ $? -ne 0 ]; then

echo "Cannot create directory $DIR"

exit 1

fi

fi

done

注意is_directory()返回0表示真返回1表示假。

阅读(567) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~