Chinaunix首页 | 论坛 | 博客
  • 博客访问: 300577
  • 博文数量: 84
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 890
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-13 16:46
文章分类

全部博文(84)

文章存档

2017年(2)

2016年(4)

2015年(78)

我的朋友

分类: LINUX

2015-06-21 18:50:10

一、判断语句if...then
简单的说就是当符合某个条件判断的时候,就进行某项工作,这个if...then的判断还有多层次的情况
1、单层、简单条件判断式
  1. if...then...fi语法总结
  2. if如果[判断点东西];then那么
  3. 执行点东西
  4. fi完结

  5. if...then...fi 语法格式
  6. if [条件判断式];then
  7. 当条件判断式成立时,可以进行的命令工作内容;
  8. fi 将if反过来写,就是fi,结束,完结if之意!
在方括号[]中&&代表and
在方括号[]中||代表or

[ "$yn" == "Y" -o "$yn" == "y" ]也可以写成[ "$yn" == "Y" ] || [ "$yn" == "y"]
之所以这样写,很多人是习惯问题。很多人则是喜欢一个中括号仅有一个判断式的原因

if...then...fi语句(单层、简单条件判断式)

  1. [root@RHEL6 scripts]# more sh06-2.sh
  2. #!/bin/bash
  3. #program:
  4. # This program shows the user's choice
  5. #History:
  6. #2015/06/16 Awake Fist release
  7. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  8. export PATH
  9. read -p "please input (Y/N):" yn
  10. #[ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK,continue" && exit 0 //这两行注释掉了,使用下面的if...then语句完成相同的功能
  11. #[ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh,interrupt!" && exit 0

  12. if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then //如果变量$yn是Y或y,那么就执行下面的两行语句
  13.         echo "OK,continue" //如果条件判断式成立,可以进行的命令工作内容
  14.         exit 0 //如果条件判断式成立,可以进行的命令工作内容,上面的命令必须执行成功才能执行此条。两行命令相当于&&
  15. fi //结束,完结

  16. if [ "$yn" == "N" ] || [ "$yn" == "n" ]; then //如果变量$yn是N或n,那么就执行下面的两行语句
  17.         echo "Ho,interrupt!"
  18.         exit 0
  19. fi

  20. echo "I dot't know what your choice is" && exit 0 //没有输入合法的字符,就显示这行
  21. [root@RHEL6 scripts]#
脚本sh06-2.sh的执行情况
  1. [root@RHEL6 scripts]# ./sh06-2.sh
  2. please input (Y/N):y //输入Y
  3. OK,continue
  4. [root@RHEL6 scripts]# ./sh06-2.sh
  5. please input (Y/N):n //输入n
  6. Ho,
  7. [root@RHEL6 scripts]# ./sh06-2.sh
  8. please input (Y/N): //无输入
  9. I dot't know what your choice is
  10. [root@RHEL6 scripts]#
if...then...fi语句(linux系统中的引用实例)
  1. [root@RHEL6 ~]# more .bashrc
  2. # .bashrc
  3. # User specific aliases and functions

  4. alias rm='rm -i'
  5. alias cp='cp -i'
  6. alias mv='mv -i'
  7. alias grep='grep --color=auto'
  8. alias vi=vim

  9. # Source global definitions
  10. if [ -f /etc/bashrc ]; then //如果/etc/bashrc这个文件存在且为文件那么就在父进程中执行. /etc/bashrc这个全局变量
  11.         . /etc/bashrc
  12. fi
  13. [root@RHEL6 ~]#

if...then...fi语句(多层、复杂条件判断式)通过脚本检测主机是否开启主要的网络服务端口
  1. [root@RHEL6 scripts]# more sh10.sh 
  2. #!/bin/bash
  3. #program:
  4. # Using netstat and grep to detect WWW,SSH,FTP and Mail services.
  5. #History:
  6. #2015/06/18 Awake First release
  7. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  8. export PATH

  9. echo "Now, I will detect your Linux server's services!"
  10. echo -"The www,ftp,ssh,and mail wibe detect! \n"

  11. testing=$(netstat -ulnt | grep ":80") //变量testing的内容为$(netstat -ulnt | grep ":80"),如果有这个netstat加grep命令有输出,就证明有这个服务
  12. if [ "$testing" != "" ]; then //如果变量$testing的内容不等于""空,那么(then)就执行下面的命令。
  13.         echo "WWW is running in your system."
  14. fi

  15. testing=$(netstat -ulnt | grep ":22")
  16. if [ "$testing" != "" ]; then
  17.         echo "SSH is running in your system."
  18. fi

  19. testing=$(netstat -ulnt | grep ":21")
  20. if [ "$testing" != "" ]; then
  21.         echo "FTP is running in your system."
  22. fi

  23. testing=$(netstat -ulnt | grep ":25")
  24. if [ "$testing" != "" ]; then
  25.         echo "Mail is running in your system."
  26. fi
  27. [root@RHEL6 scripts]#
  脚本sh10.sh的执行情况
  1. [root@RHEL6 scripts]#. sh10.sh 
  2. Now, I will detect your Linux server'
  3. The www,ftp,ssh,and mail wibe 

  4. SSH is running in your system. //我的系统上只有两个服务22和25,因此此处就输出了两个
  5. Mail is running in your system.
  6. [root@RHEL6 scripts]#



2、多重、复杂条件判断式

在同一个数据的判断式中,如果该数据需要进行多种不同的判断时,应该怎么做?上面的sh06-2脚本中,我们只要执行一次$yn的判断就好(仅进行一次fi),不要做多次if的判断,此时你就得知道下面的语法了;

  1. #一个条件判断
  2. if [ 条件判断式 ];then
  3. 当条件判断式成立时,可以进行的命令工作内容;
  4. else(否者、其他、别的)
  5. 当条件判断式不成立时,可以进行的命令工作内容;
  6. fi

  7. if...then...else...fi语法总结
  8. if如果[判断点东西];then那么
  9. 执行点东西
  10. else否则
  11. 否则执行另外的东西
  12. fi完结
判断某个用户是否登陆的linux脚本,使用了if...then..else...if语句
  1. #!/bin/bash
  2. read -p "Please enter a user name to detect:" username  //让用户输入变量的名字,这里是提示用户输入用户名
  3. w | grep $username                                      //w | grep 命令找到用户设定的变量(用户名)
  4. if [ $? -eq 0 ];then                                    //如果[条件判断式]成立也就是w | grep $username执行成功那么系统会返回一个$?=0的回传码,就执行下面的语句,变量$username已经登录
  5. echo "$username User logged in"
  6. else                                                    //如果$?为非零那么就执行下面的语句,告诉用户变量$username没有登录。
  7. echo "$usename Users didn‘t log in"
  8. fi                                                      //完结
如果考虑更复杂的情况,则可以使用这个语法
  1. #多个条件判断(if...elif...else)分多种不同情况执行
  2. if [ 条件判断式一 ];then
  3. 当条件判断式一成立时,可以进行的命令工作内容
  4. elif [ 条件判断式二 ];then
  5. 当条件判断式二成立时,可以进行的命令工作内容;
  6. else
  7. 当条件判断式一与二均不成立时,可以进行的命令工作内容
  8. fi

  9. if...then...elif...else...fi语法总结
  10. if如果[判断点东西];then那么
  11. 执行点东西
  12. elif 再如果,判断点东西
  13. 在执行点东西
  14. else否则
  15. 否则(以上两个判断都不是的情况)执行另外的东西
  16. fi完结
if...then...elif...else...fi语句实例(将sh06.sh与sh06-2.sh改造
  1. [root@RHEL6 scripts]# more sh06-3.sh
  2. #!/bin/bash
  3. #program:
  4. # This program shows the user's choice
  5. #History:
  6. #2015/06/16 Awake Fist release
  7. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  8. export PATH
  9. read -p "please input (Y/N):" yn
  10. #使用条件判断式加&&的方法
  11. #[ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK,continue" && exit 0
  12. #[ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh,interrupt!" && exit 0
  13. #使用if...then条件判断式
  14. #if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
  15. # echo "OK,continue"
  16. # exit 0
  17. #fi

  18. #if [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
  19. # echo "Ho,interrupt!"
  20. # exit 0
  21. #fi
  22. #使用if...then...elif...else...fi多重条件判断式
  23. if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
  24.         echo "OK,continue" //当条件判断式二成立时,可以进行的命令工作内容;
  25.         exit 0
  26. elif [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
  27.         echo "Ho,interrupt!" //当条件判断式一成立时,可以进行的命令工作内容;
  28.         exit 0
  29. else
  30.         echo "I dot't know what your choice is" //当条件判断式一与二均不成立时,可以进行的命令工作内容
  31. fi
  32. [root@RHEL6 scripts]#
if...then...elif...else...fi语句实例(脚本参数($1)的设置)
一般说,如果你不希望用户用键盘输入额外的数据时,可以使用脚本的参数功能$1!,让用户在执行命令时就将参数代入进去。现在我们想让用户输入“hello”这个关键字时,利用参数的方法可以这样依次设计:
1、判断$1是否为hello,如果是的话,就显示“Hello,how are you?”;(实际应用可能是命令,service network restart,network即为脚本,如果判断参数是restart那么就执行重启的脚本)
2、如果没有加任何参数,就提示用户必须要使用的参数;
3、而如果加入的参数不是hello,就提醒用户仅能使用hello为参数,系统中的实例就像这样
  1. [root@RHEL6 ~]# service network
  2. Usage: /etc/init.d/network {start|stop|status|restart|reload|force-reload}  //大括号中的参数即为$1
  3. [root@RHEL6 ~]#
实例
  1. [root@RHEL6 scripts]# more sh09.sh
  2. #!/bin/bash
  3. #program:
  4. # Check $1 is equal to "hello"
  5. #History:
  6. #2015/06/18 Awake First release
  7. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  8. export PATH

  9. if [ "$1" == "hello" ]; then //如果变量$1是hello,那么就执行下面的语句
  10.         echo "Hello,how are you ?"
  11. elif [ "$1" == "" ]; then //如果变量$1是空,那么就执行下面的语句
  12.         echo "You MUST input parameters,ex > {$0 someward}" //提示在脚本($0)后面应该输入些字符
  13. else
  14.         echo "The only parameter is 'hello' , {ex > $0 hello}" //既没有输入正确的字符,也没有字符,那么提示用户输入正确字符
  15. fi
  16. [root@RHEL6 scripts]#
实例执行情况
  1. [root@RHEL6 scripts]# ./sh09.sh
  2. You MUST input parameters,ex > {./sh09.sh someward}
  3. [root@RHEL6 scripts]# ./sh09.sh adfad
  4. The only parameter is 'hello' , ex > {./sh09.sh hello}
  5. [root@RHEL6 scripts]# ./sh09.sh hello
  6. Hello,how are you ?
  7. [root@RHEL6 scripts]#

if...then...fi和if...then...else...fi混合应用(让用户输入他的退伍日期,让你去计算还有几天才退伍)

由于日期是要用相减的方式来处理,所以我们可以通过使用date显示日期与时间,将它转为由1970-01-01累积而来的秒数,通过秒数相减取得剩余的秒数后,再换算为日数即可。
1、先让用户输入他们的退伍日期;
2、再由现在日期对比退伍日期;
3、由两个日期的比较来显示“还需要几天”才能够退伍的字样。
利用“date --date= +%s”转成秒数后,接下来的操作就容易多了
  1. [root@awake scripts]# more sh11.sh
  2. #!/bin/bash
  3. #Program:
  4. # You input your demobilization date, i calculate now many days before you demobilize.
  5. #History:
  6. #2015/06/18 Awake First release
  7. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  8. export PATH

  9. echo "This program will try to colculate :"
  10. echo "How many days before your demobilization date ..."

  11. read -p "Please input your demobilization date (YYYYMMDD ex>20180401):" date2 //让用户输入date2的变量内容如20180401这样的八位数的日期

  12. date_d=$(echo $date2 | grep '[0-9]\{8\}') //利用正则表达式测试一下输入的内容是否正确,看看是否有八个数字,我在shell下测试如果仅输入echo 12345678 | grep '[0-9]\{8\}',那么可以输出12345678这个数字,如果输入的位数不够,或者不是数字那么就没有显示
  13. if [ "$date_d" == "" ]; then //如果date_d这个变量内容是空,那么就执行下面的语句告诉用户输入的格式不对,退出,并返回值为1(1代表什么是OS error code 1: Operation not permitted)
  14.         echo "You input the wrong date format...."
  15.         exit 1
  16. fi
  17. //开始计算日期,这部分的计算是建立在用户输入了8位数字的前提下的
  18. declare -i date_dem=`date --date="$date2" +%s` //声明变量date_dem(退伍日期)的秒数,也即1970年1月1日至输入的日期($date2)的秒数(这两行我认为没有整数运算,只是一个变量名等于一个命令而已,可以将declare -i去掉,我试过去掉也是正常的)
  19. declare -i date_now=`date +%s` //声明变量date_now为现在的时间,也即1970年1月1日至现在系统时间的秒数
  20. declare -i date_total_s=$(($date_dem-$date_now)) //声明变量date_total_s的数值为退伍时间减去现在的时间,即还有多少时间(秒)退伍?
  21. declare -i date_d=$(($date_total_s/60/60/24))  //这个date_d不要和上面的date_d变量混淆,是剩余的秒数除以60秒、60分钟、24小时,即得剩余天数(这种格式只支持整数的算法)

  22. if [ "$date_total_s" -lt "0" ]; then //判断是否退伍,如果$date_total_s小于0了,也就是用户输入了一个历史时间,那么执行下面的命令,提示表示已经退伍了,并且显示退伍多少天了,$((-1*$date_d))只是将那个小于0的数值(负数)变成正数
  23.         echo "You had been demobilization before:" $((-1*$date_d)) "ago"
  24. else //否则,执行下面的命令,
  25.         declare -i date_h=$(($(($date_total_s-$date_d*60*60*24))/60/60)) //其实是两层计算式,编者是要算出除几天外,还有几个小时,看来真是迫切啊!先从最里边开始看,还有多少时间退伍(秒数)减去剩余的天数乘以60秒、60分、24小时(也是秒数,只不过这个秒数是整天的秒数,没有余数的)得到的结果也就是一天中剩下的秒数,在除以60秒、60分,也就是小时数了。
  26.         echo "You will demobilize after $date_d days and $date_h hours."
  27. fi
  28. [root@awake scripts]#//其实我感觉这个例子挺难理解的,估计也是编者做了多方测试,得到的结果。
脚本sh11.sh执行验证情况1,输入一个未来时间20160101
  1. [root@awake scripts]# ./sh11.sh
  2. This program will try to colculate :
  3. How many days before your demobilization date ...

  4. Please input your demobilization date (YYYYMMDD ex>20180401):20160101
  5. You will demobilize after 195 days and 23 hours. //得到的天数还有小时
脚本sh11.sh执行验证情况2,不输入任何内容
  1. [root@awake scripts]# ./sh11.sh
  2. This program will try to colculate :
  3. How many days before your demobilization date ...

  4. Please input your demobilization date (YYYYMMDD ex>20180401):
  5. You input the wrong date format....
脚本sh11.sh执行验证情况3,输入不符合规范的内容
  1. [root@awake scripts]# ./sh11.sh
  2. This program will try to colculate :
  3. How many days before your demobilization date ...

  4. Please input your demobilization date (YYYYMMDD ex>20180401):hljhljk //输入的不符合规范的内容
  5. You input the wrong date format....
  6. [root@awake scripts]#
脚本sh11.sh执行验证情况4,输入一个历史事件;
  1. [root@RHEL6 scripts]# ./sh11.sh
  2. This program will try to colculate :
  3. How many days before your demobilization date ...

  4. Please input your demobilization date (YYYYMMDD ex>20180401):20141212  //输入一个过去的事件
  5. You had been demobilization before: 193 ago    //提示你已经退役了193天
  6. [root@RHEL6 scripts]#
二、利用case... esac判断

if...then...fi对于变量的判断是以比较的方式来分辨的,如果符合状态就进行某些行为,并且通过较多层次(就是elif)的方式来进行多个变量的程序代码编写,譬如sh09.sh那个小程序,就是用这样的方式来编写的。那么万一我有多个设定的变量内容,录入sh09.sh当中,我所需要的变量就是hello及空格字符串两个,那么我只要针对这两个变量来设置情况就好了,那么我们就用case...in...esac,它的语法如下:
  1. case $变量名称 in //关键字为case,还有变量前有$
  2. "第一个变量内容"//每个变量内容建议用双引号括起来,关键字则为小括号
  3. 程序段
  4. ;; //每个类型结尾使用两个连续的分号来处理
  5. "第二个变量内容"
  6. 程序段
  7. ;;
  8. *) //最后一个变量内容都会用*来代表所有其他值
  9. 不包含第一个变量内容与第二个变量内容的其他程序执行段
  10. exit1
  11. ;;
  12. esac //最终的case结尾!“反过来写” 思考一下!
这个语法以case(实际案例之意)为开头,结尾自然就是case的应为反过来写。就成为esac。不会很难背!另外每一个变量内容的程序段最后都需要两个分号(;;)来代表该程序段落的结束,这很重要,至于为何需要有*这个变量内容在最后呢?这是因为,如果用户不是输入第一个或第二个变量内容时,我们可以告知用户相关的信息。
复习一下sh09.sh实例
  1. [root@RHEL6 scripts]# more sh09.sh
  2. #!/bin/bash
  3. #program:
  4. # Check $1 is equal to "hello"
  5. #History:
  6. #2015/06/18 Awake First release
  7. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  8. export PATH

  9. if [ "$1" == "hello" ]; then //如果变量$1是hello,那么就执行下面的语句
  10.         echo "Hello,how are you ?"
  11. elif [ "$1" == "" ]; then //如果变量$1是空,那么就执行下面的语句
  12.         echo "You MUST input parameters,ex > {$0 someward}" //提示在脚本($0)后面应该输入些字符
  13. else
  14.         echo "The only parameter is 'hello' , {ex > $0 hello}" //既没有输入正确的字符,也没有字符,那么提示用户输入正确字符
  15. fi
  16. [root@RHEL6 scripts]#
使用case in ) ;; esac语法(对脚本参数$1进行判断)
  1. [root@awake scripts]# more sh09-2.sh
  2. #!/bin/bash
  3. #Program
  4. # show "Hello" from $1... by using case... esac
  5. #History:
  6. #2015/06/19 Awake First release
  7. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  8. export PATH

  9. case $1 in //$1是变量名称,感觉像是case(案例)变量$1 in(的内容)检查
  10.   "hello") //如果变量内容为hello,那么就执行下面的命令
  11.         echo "Hello,how are you ?"
  12.         ;; //另外每一个变量内容的程序段最后都需要两个分号(;;)来代表该程序段落的结束
  13.   "") //如果变量内容为空,这执行下面的命令
  14.         echo "You MUST input parameters, ex> {$0 someword}"
  15.         ;;
  16.   *) //其实就相当于通配符,0~无穷多任意之意,也就是不包含第一个变量内容与第二个变量内容的其他程序执行段。在屏幕上显示下面的命令内容
  17.         echo "usage $0 {hello}"
  18.         ;;
  19. esac //相当于fi,完结之意
  20. [root@awake scripts]#
脚本sh09-2.sh执行情况
  1. [root@awake scripts]# chmod 744 sh09-2.sh
  2. [root@awake scripts]# ./sh09-2.sh    //不输入任何字符,匹配的是"")
  3. You MUST input parameters, ex> {./sh09-2.sh someword}
  4. [root@awake scripts]# ./sh09-2.sh 123  //输入错误字符,匹配的是*)
  5. usage ./sh09-2.sh {hello}
  6. [root@awake scripts]# ./sh09-2.sh hello //输入正确字符,匹配的是"hello")
  7. Hello,how are you ?
  8. [root@awake scripts]#
      上面这个案例中,如果你输入sh sh09-2.sh 123来执行,那么屏幕上就会出现Usage sh09-2.sh {hello}的字眼,告诉执行者仅能使用hello这个脚本参数,这种的方式对于需要某些固定字符串来执行的变量内容就显得更加方便!这种方式你真的需要熟悉,这是因为系统的很多服务的启动script都是使用这种写法的,举例来说,我们的linux的服务启动放置目录是在/etc/init.d/当中,我们已经知道里头有一个rsyslog的服务,我们想要重启这个服务,可以这样做
  1. [root@awake init.d]# /etc/init.d/rsyslog restart //重启这个服务
  2. [root@awake init.d]# /etc/init.d/rsyslog //你可以直接执行/etc/init./rsyslog去查阅一下,这个脚本到底有多少个脚本参数
  3. Usage: /etc/init.d/rsyslog {start|stop|restart|condrestart|try-restart|reload|force-reload|status}
如果你使用less /etc/init.d/rsyslog去查阅一下,就会看到它使用的是case语法,并且会规定某些既定的变量内容。如rsyslog文件的一部分内容为:
  1. case "$1" in
  2.   start) //$1的变量内容为start那么就执行下面的命令start,start是一个/sbin下的的可执行文件
  3.         start
  4.         ;;
  5.   stop)
  6.         stop
  7.         ;;
  8.   restart)
  9.         restart
  10.         ;;
  11.   reload)
  12.         exit 3
  13.         ;;
  14.   force-reload)
  15.         restart
  16.         ;;
  17.   status)
  18.         rhstatus
  19.         ;;
  20.   condrestart|try-restart)
  21.         rhstatus >/dev/null 2>&1 || exit 0
  22.         restart
  23.         ;;
  24.   *) //如果以上都不是就显示如下信息。告诉用户合法的参数字符。
  25.         echo $"Usage: $0 {start|stop|restart|condrestart|try-restart|reload|force-reload|status}"
  26.         exit 3
  27. esac
一般来说,使用“case $变量 in”这个语法中,当中的那个“$变量”大致有两种取得的方式;
直接执行式:例如上面提到的,利用“script.sh veriable”的方式来直接给予$1这个变量的内容,这也是在/etc/init.d目录下大多数程序的设计方式。
交互式:通过read这个命令来让用户输入变量的内容。
  1. [root@awake scripts]# more sh12.sh
  2. #!/bin/bash
  3. #program
  4. # This script only accepts the flowing parameter:one,two or three.
  5. #History:
  6. #2015/06/19 Awake First release
  7. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  8. export PATH

  9. echo "This program will print your selection !"
  10. #read -p "Input your choice: " choice //暂时取消
  11. #case $choice in //暂时取消
  12. case $1 in //现在使用的,可以用上面两行替换!
  13.   "one")
  14.         echo "you choice is ONE"
  15.   ;;
  16.   "two")
  17.         echo "you choice is TWO"
  18.   ;;
  19.   "three")
  20.         echo "you choice is Three"
  21.   ;;
  22.   *)
  23.         echo "Usage $0 {one|two|three}"
  24.   ;;
  25. esac
  26. [root@awake scripts]#
此时,你可以使用sh sh12.sh two的方式来执行命令,就可以收到相对应的响应了。上面使用的是直接执行的方式,而如果使用的是交互式时,那么将上面第10/11行的#去掉,并将12行加上批注(#),就可以让用户输入参数。

三、利用function功能
什么是函数(function)功能?简单地说,其实,函数可以在shell script当中做出一个类似自定义执行命令的东西,最大的功能是,简化我们很多的程序代码。举例来说,上面的sh12.sh当中每个输入结果 one、two、three其实输出的内容都一样,那么我就可以使用function来简化
  1. function的语法是
  2. function fname (){
  3. 程序段
  4. }
那个fname(功能名称)就是我们的自定义的执行命令名称,而程序段就是我们要他的执行内容了,要注意的是,因为shell script的执行方式是由上而下,由左而右,因此在shell script当中的function的设置一定要在程序的最前面(有点像声明的变量),这样才能够在执行时被找到可用的程序段。
  1. [root@awake scripts]# more sh12-2.sh
  2. #!/bin/bash
  3. #program
  4. # This script only accepts the flowing parameter:one,two or three.
  5. #History:
  6. #2015/06/19 Awake First release
  7. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  8. export PATH

  9. function printit (){ //自定义的执行命令名称为printit,空括号{}中的程序段,就是我们要他执行的内容了
  10.         echo -n "Your choice is "
  11. }

  12. echo "This program will print your selection !"
  13. case $1 in
  14.   "one")
  15.         printit; echo $1 | tr 'a-z' 'A-Z' //printit在这里已经变成了一个命令,也就是替代echo -n “Your choice is”的执行,后面紧接着再输出的echo $1内容做大小写转换并且没有换行是因为printit中的echo -n参数作用
  16.   ;;
  17.   "two")
  18.         printit; echo $1 | tr 'a-z' 'A-Z' //tr 'a-z' 'A-Z'将参数做大小写转换
  19.   ;;
  20.   "three")
  21.         printit; echo $1 | tr 'a-z' 'A-Z'
  22.   ;;
  23.   *)
  24.         echo "Usage $0 {one|two|tree}"
  25.   ;;
  26. esac
  27. [root@awake scripts]#
以上的例子,是先做了一个函数名称为printit,所以,当我们在后续的程序段里面,只要执行printit的话,就表示我的shell script要去执行function printit () {echo -n "Your choice is "}。如果某些程序代码一再地在script中重复是,这个function可就重要得多,它不但可以简化程序代码,而且可以做成类似“模块”的玩意。

脚本sh12-2.sh的执行情况
  1. [root@awake scripts]# ./sh12-2.sh one //输入合法的参数(one),匹配"one")
  2. This program will print your selection !
  3. Your choice is ONE   //正确的输出,其中ONE为大写字母,匹配的是执行命令printit; echo $1 | tr 'a-z' 'A-Z'
  4. [root@awake scripts]# ./sh12-2.sh     //不输入任何参数
  5. This program will print your selection !  
  6. Usage ./sh12-2.sh {one|two|tree}      //提示用户输入正确的参数,匹配*)和echo "Usage $0 {one|two|tree}"
  7. [root@awake scripts]# ./sh12-2.sh two
  8. This program will print your selection !
  9. Your choice is TWO
  10. [root@awake scripts]# ./sh12-2.sh three
  11. This program will print your selection !
  12. Your choice is THREE
  13. [root@awake scripts]# ./sh12-2.sh adaf //输入错误的参数
  14. This program will print your selection !
  15. Usage ./sh12-2.sh {one|two|tree}    //提示用户输入正确的参数,匹配*)和echo "Usage $0 {one|two|tree}"
  16. [root@awake scripts]#
另外,function也是拥有内置变量的,它的内置变量与shell script很类似,函数名称代表是$0,而后续接的变量也是以$1,$2...来替代的。这里很容易搞错,因为“function fname () {程序段}”内的$0、$1等与shell script 的$0是不同的。以上面sh12-2.sh来说,假如我们执行sh sh12-2.sh one这个表示在shell script内的$1为one这个字符串。但是在printit()内的$1则与这个one无关。我们将sh12-2.sh再次改写一下,让你更清楚!
  1. #!/bin/bash
  2. #program
  3. #    Use function to repeat information
  4. #History
  5. #2015/06/19 Awake First relase
  6. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
  7. export PATH


  8. function printit (){
  9. echo "Your chice is $1" //$1写在这代表是function的内置变量,而不是shell script sh12-3.sh的脚步参数。这个$1必须要参考下面命令的执行
  10. }


  11. echo "This program will print your selection !"
  12. case $1 in
  13. "one")
  14. printit 1 //printit后面的1会成为function当中的$1
  15. ;;
  16. "two")
  17. printit 2
  18. ;;
  19. "three")
  20. printit 3
  21. ;;
  22. *)
  23. echo "Usage $0 {one|two|three}"
  24. ;;
  25. esac
      上面的例子当中,如果你输入“sh sh12-3.sh one”就会出现Your choice is 1的字眼。为什么是1呢?因为在程序段落当中,我们是写了printit 1那个1会成为function当中的$1.
  1. [root@awake scripts]# ./sh12-3.sh
  2. This program will print your selection !
  3. Usage ./sh12-3.sh {one|two|three}
  4. [root@awake scripts]# ./sh12-3.sh one
  5. This program will print your selection !
  6. Your chice is 1
  7. [root@awake scripts]# ./sh12-3.sh two
  8. This program will print your selection !
  9. Your chice is 2
  10. [root@awake scripts]# ./sh12-3.sh three
  11. This program will print your selection !
  12. Your chice is 3
  13. [root@awake scripts]# ./sh12-3.sh adsfadfasd
  14. This program will print your selection !
  15. Usage ./sh12-3.sh {one|two|three}
  16. [root@awake scripts]#



阅读(1354) | 评论(0) | 转发(0) |
0

上一篇:linux $?的含义

下一篇:linux date命令

给主人留下些什么吧!~~