Chinaunix首页 | 论坛 | 博客
  • 博客访问: 137350
  • 博文数量: 25
  • 博客积分: 389
  • 博客等级: 一等列兵
  • 技术积分: 838
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-23 14:18
文章存档

2013年(20)

2012年(5)

分类: LINUX

2013-03-10 11:28:38

我们已经知道如何使用shell的命令行界面提示输入命令和查看命令结果,而shell脚本的关键可以输入多条命令,处理每一条命令的结果,甚至可以将一条命令的结果传递给另一条命令,shell可以将多条命令连接起来形成单一的步骤。
1、下面我就说说如何创建脚本文件:
   要将shell命令放置在一个文本文件中,首先需要使用文本编辑器创建一个文件,然后将命令输入到该文件中,创建脚本文件是,必须在文件的第一行指明所使用的shell。格式如下:
#!/bin/bash
# This scripts displays the date and who`s logged on
date
who
在普通的shell脚本行中,#符号用作注释行,shell不处理shell脚本中的注释行,但是shell脚本中的第一行是个特例,#后面跟着!号是在告诉shell运行下列脚本的shellbash shell,也可以用其它的shell,一般我们用bash shell,用#号添加注释行是为了方便我们以后回顾以往的工作,编辑完了上面的一个简单的小脚本之后我们可以将他们保存起来,我们可以命名为我们方便管理的文件名,这里我们命名为test1,然后我们要使bash shell能找到test1脚本文件,因为shell使用名为PATH的环境变量查找命令,要使shell能找到test1脚本文件,需要下列任意一种操作即可:
1、  shell脚本文件所在的目录添加到PATH环境变量中;
2、  在命令提示符中使用文件的绝对路径或相对路径来引用该shell脚本。
    下面我们用第二种方法将test1文件的准确路径告诉给shell,查看执行结果如下:
  
 
    我们发现执行结果是错误的,提示我们没有执行test1文件的权限,我们快速的查看一test1文件的权限:
 
    因为我们创建新的test1文件时,umask值确定了新文件的默认权限设置,
由于umask设为022,所以系统以只读只写的权限创建了该文件,下一步我们要
赋予test1文件可执行的权限然后查看执行结果:
    经过我们创建test1脚本文件、将test1文件的准确路径告诉给shell和给
test1文件可执行权限后脚本执行成功了,通过上述讲述,我们就很轻松的
解了shell脚本的基本编译方法。
2、显示消息:
大多数shell命令生成自己的输出,这些输出在运行该脚本的控制台监视器上显示,有时候想添加自己的文本消息以帮助脚本用户了解脚本中发生了什么,使用echo命令可以完成此操作,下面我们来了解一下echo命令的使用:
echo 用来显示回显信息;其命令选项有以下几个:
    -e 解析反斜杠命令,例如\n(换行符)
    -n 解除系统换行;
    例如:
    默认情况下不需要使用引号来标记想要显示的字符串,但是如果在字符串
中使用了引号,有时会出现问题,例:
    echo命令可以用单引号或双引号来标记文本字符串;要想使上述字符串完
整的显示出来,就要对上述字符串整体使用双引号标记;执行结果如下:
-e 解析反斜杠命令,例如\n(换行符)\t(水平制表符),例:
-n 解除系统换行,例:
3、使用变量:
变量:可变化的量,有名称的内存空间,运行在进程的内存空间中;
  1)bash中变量的类型:bash中所有的变量类型都理解为字符型);
   环境变量  环境变量对当前shell及其子shell都是有效的;
   本地变量 (局部变量)只对当前shell有效,作用域为当前shell
   特殊变量 $? 引用上一条命令的执行状态返回值;
       0  执行成功;
        1-255  执行失败,其中12127通常是预留的;
       位置变量 位置变量用于引用传递过来的函数:通常用$1,$2....${11},...
  2)变量命名:
      1、只能包含字母、数字和下划线:并且不能以数字开头;
      2、不能与关键字冲突;
      3、见名知义;
          例:date=
                  stu_total=
  3)变量的事先声明:
declare [options] VAR_NAME
        -i 整型
        -x 环境变量
        -a 数组
            -r 只读变量,值不能改变并且不能撤销;
      声明局部变量 例:Local NAME=Jerry
          声明环境变量 例:declare –x VAR_NAME=vale
                        export VAR_NAME=valeprintenv VAR_NAME=vale
4、输入/输出重定向和管道
     程序的重要功能:读入数据—>处理—>输出数据;
      定义一个默认的数据读入的设备,数据输出的设备;
         0:标准输入的文件描述符,通常对应的是keyboard(键盘);
         12:标准输出的文件描述符,通常对应的是monitor(显示器);
              正确执行1,monitor
              错误执行2,monitor
1)输出重定向:
>  覆盖重定向;
>> 追加重定向;
>OUT 2>&1 将两种数据的输出流合并,例如:cat /etc/fstab >/tmp/test 2>&1
               set -C  开启禁止覆盖已存在的文件的功能;
               set +C  关闭禁止覆盖已存在的文件的功能;
>| 允许覆盖,例如:cat /etc/fstab >| /tmp/test
&>  合并输出流至同一个数据流,例如:例如:cat /etc/fstab &> /tmp/test
2)输入重定向:
 输入重定向,例如:mail -s “hello” root > /etc/fstab
<<  Here Document表示此处作为文档使用,例如:cat << EOF
                                                   hello
                                                   ni hao 
                                               EOF      
                                               表示见EOF结束   
3)如何自己定义文件描述符并取消文件描述符:
    exec 是个内置命令,用某一个命令把这个shell进程替换掉;
exec n> /to/somewhere 定义文件描述符到某一个位置;
n>> 
n<  自己定义标准输入设备;
<> 把后面的设备即是输入又是输出;
exec n>&-  关闭我们自己定义的文件描述符;
          exec 3> /tmp/a  定义3这个文件描述符,把它的设备输出到/tmp/a下的a文件,例如:
4)管道  |  把前一个命令的输出当作后一个命令的输入 ;
COMMAND1 | COMMAND2 | COMMAND3.........
例如:
5、条件测试:
        [ expression ]  注意空格,单中括号是命令
 [[ expression ]]  双中括号是关键字
         test expression
expression写法
     bash的条件测试类型:
1、  整数测试;
2、  字符串测试;
3、  文件测试;
      1)整数测试;
             双目操作:NUM1 操作符 NUM2
                   
-eq  等于 ;例如:[ 2 -eq 3 ]或[[ 2 -eq 3 ]]或test 2 -eq 3;
                    -gt  大于;
                    -lt  小于;
                    -ge  大于等于;
                    -le  小于等于;
                    -ne  不等于;
       2)字符串测试:
               >,<,>=,<=,!=,==
              [[]]  用于字符串比较;
        单目:-z “STRING”  测试字符串是否为空;
              -n “STRING”  测试字符串是否不空;
       3)文件测试:
       -e /path/to  测试文件是否存在(/path/to可以是目录或着链接);
       -f /path/to  测试文件是不是文件(/path/to可以是目录或着链接);
       -d /path/to  测试文件是不是目录(/path/to可以是目录或着链接);
       -r /path/to  测试是否有读权限(/path/to可以是目录或着链接);
       -w /path/to  测试是否有写权限(/path/to可以是目录或着链接);
       -x /path/to  测试是否有执行权限(/path/to可以是目录或着链接);
 4)实现算术运算:
     $[expression]
         常用方法:
            赋值给变量,例如:SUM=$[2+3]
            使用echo回显,例如:echo $[2+3]
 $(()),例如:SUM=$((2+3))或echo $((2+3));
 let VAR_NAME=NUM1 OP NUM2,例如:let SUM=2+3
expr 2 + 3(注意加号两边的空格)
5)算术运算方式:
          $[算式]SUM=$[$SUM+$I]
          $(算式):SUM=$(($SUM+$I))
         
`expr 算式`:例如:SUM=`expr 算式`:SUM=`expr $SUM + $I`
        
(注意算术符号两边的空格)
6、命令替换
1)引号的作用:
          单引号:强引用;
          双引号:变量替换;
              反引号:` 命令引用,过程是命令替换的过程;
2)命令替换的命令方式
`COMMANG`或者是$(COMMAND)
变量引用:
          $VAR_NAME
          $(VAR_NAME)
set VAR_NAME=value
unset VAR_NAME   撤销变量

7if判断

    1)单分支:
      如果满足,那么;
      statement1
      statement2
      结束
    例: 
  1. #!/bin/bash
  2. #
  3. if [ ! –e /tmp/abc ]; then
  4.      mkdir /tmp/abc
  5. fi
    2)双分支:
         如果存在;那么
           显示目录已经存在
         否则(可以缺省)
           创建目录;
           说明创建成功;
         结束 
         例:
  1. #!/bin/bash
  2. #
  3. if [ –e /tmp/abc ]; then
  4.     echo “abc is exits.
  5. else
  6.     mkdir /tmp/abc
  7.     echo “Create success.
  8. fi
   (a)连接两个条件符号:
      -a  与关系,举例:[ $UID –ge –a $UID –le 499 ];
      -o  表示或关系;
      !   表示非关系;
3)多分支:
      (if)如果满足条件一;
             语句
      (elif)如果满足条件二;
             语句
      (elif)如果满足条件三;
             语句
      (else)否则(可以缺省);
             语句
      (fi)结束 
  1. 例:#!/bin/bash
  2.     #
  3.     USERID=`id –u user1 `
  4.     if [ $USERID –eq 0 ];
  5.        then echo “Admin”
  6.     elif [ $USERID –ge 1 –a $USERID –le 499 ];
  7.        then encho “System”
  8.     else
  9.        echo “Common user”
  10.     fi  
    4if嵌套: 
  1. if 条件1;then
  2.    if 条件2;then
  3.       statement
  4.    fi
  5.  else
  6.    statement
  7.  fi
  例:某文件存在时,就判断文件类型,不存在时,就说明此文件不存在; 
  1. if [ -e FILE ];then
  2.    if [ -f FILE ];then
  3.       echo “Common.
  4.    elif [ -d FILE ];then
  5.       echo “Directory.
  6.    else
  7.       echo “Uknown.
  8.    fi
  9.  else
  10.    echo “Its not exits.
  11.  fi

8for循环 

  1. for 变量(用于赋值的,一定不要加$符) in 列表;do
  2.       statement1
  3.       statement2
  4.       …
  5. done
    1)遍历列表,有穷,比如 18表示为1 2 3 4 5 6 7 8 
  1. 例:SUM=0
  2.     for I in 1 2 3 4 5 6 7 8;do
  3.        SUM=$[$SUM+$I]
  4.     done
  5.        echo $SUM
    2)列表表示法   0100表示为{1..100}`seq 1 100` 
  1. 例:用for循环实现从1到1000之和
  2.         declare –i SUM=0
  3.         for I in {1…1000};do
  4.            SUM=$[$SUM+$I]
  5.         done
  6.            echo $SUM
  7.      例: ping 192.168.0.1到0.20主机是否联通
  8.         for I in `seq 1 20`;do
  9.             ping 192.168.0.$I
  10.         done

9while循环:在条件满足时进入循环,直到条件不满足时退出; 

  1. while 条件;do
  2.       循环体
  3. done
  4.  例:1到100所有整数之和:
  5.      declare –i SUM=0
  6.      declare –I COUNT=1
  7.      while [ $COUNT –le 100 ];do
  8.         SUM=$[$SUM+$COUNT]
  9.         let COUNT++
  10.      done
  11.  例:100以内所有偶数之和
  12.      declare -i SUM=0
  13.      declare -i COUNT=2
  14.      while [ $COUNT –le 100 ];do
  15.      SUM=$[$SUM+$COUNT]
  16.      let COUNT=$[$COUNT+2]
  17.      done  

10case语句,用来替换多分支if语句; 

  1. case $变量 in
  2. 取值1)
  3.          语句
  4.          ;;
  5. 取值2)
  6.          语句
  7.          ;;
  8. 取值3)
  9.          语句
  10.          ;;
  11. *)
  12.          语句
  13.           ;;
  14. esac  

    例:
  1. #!/bin/bash
  2. #
  3. read -p "A char:" CHAR
  4. case $CHAR in
  5. [a-z]
  6.     echo "Char."
  7.     ;;
  8. [0-9]
  9.     echo "Digit."
  10.     ;;
  11. ?)
  12.     echo "Others."
  13. esac 

11until循环while循环是取反的关系;

  1. until 条件;do
  2.    循环体
  3. done 

 例:100以内所有正整数的和; 
  1. #!/bin/bash
  2. #
  3. declare –i SUM=0
  4. declare –i I=0
  5. until [ $I -gt 100 ];do
  6.     let SUM=$[$SUM+$I]
  7.     let I++
  8. done
  9.     echo $SUM 

12exit 用于指定结束脚本;

    exit N
    N为状态返回值;0,1-255
    (如果没有明确指定脚本状态返回值,脚本最后一条命令的执行状态即是脚本返回值);
     例: 
  1. #!/bin/bash
  2. #
  3. read -p "A disk:" DISK
  4. read -p "Will destroy all data on $DISK, continue?" CHOICE
  5. if [ "$CHOICE" = 'y' ];then
  6. dd if=/dev/zero of=$DISK bs=512 count=1 &> /dev/null
  7. else
  8. echo "Quit."
  9. exit
  10. fi  

13、break 停止循环,与exit的区别是exit是退出脚本;

例:

  1. #!/bin/bash
  2. #
  3. declare -i I=0
  4. while true;do
  5.     sleep 2
  6.     let I++
  7.     [ $I -eq 5 ] && break
  8. done
  9. echo $I 


14、continue 退出当前这一次循环,而提前进入下一次循环;

例:1100之内的偶数之和;

  1. #!/bin/bash
  2. #
  3. let SUM=0
  4. let I=1
  5. while [ $I -le 100 ];do
  6.     if [ $[$I%2] -eq 1 ];then
  7.        let I++
  8.        continue
  9.     fi
  10.     SUM=$[$SUM+$I]
  11.     let I++
  12. done 
  13. echo $SUM


15、脚本的函数 是独立的功能模块,主要是为了实现代码重用;

bash中定义函数的方法:

  1. 方式一:
  2.         function FUNC_NAME {
  3.         body
  4.         }
  5. 方式二:
  6.         FUNC_NAME() {
  7.         body
  8.         }
  9. 例:
  10.         #!/bin/bash
  11.         #
  12.         showecho() {
  13.         echo “How are you!”
  14.         }
  15.         for I in {1..10};do
  16.         showecho
  17.         done


1)函数的返回值:
        是函数调用时所执行的函数体中的最后一条语句的状态返回值;
    2)自定义函数返回值:
          return #
    例:
  1. #!/bin/bash
  2. #
  3. JUSER () {
  4.       if id -u root &> /dev/null;then
  5.            return 0
  6.       else
  7.            return 1
  8.       fi
  9. }
  10.  
  11. JUSER &> /dev/null
  12. echo $?
3)函数还能接受参数:
     例:./a.sh a b
             $1 $2 

  1. #!/bin/bash
  2. #
  3. SUM(){
  4.      local SUMARY=0
  5.      SUMARY=$[$1+$2]
  6.      echo $SUMARY
  7. }
  8.  
  9. SUM 5 6

  1. #!/bin/bash
  2. #
  3. SUM () {
  4.      local SUMARY=0
  5.      SUMARY=$[$1+$2]
  6.      echo $SUMARY
  7. }
  8.  
  9. for I in {1..100};do
  10.      SUM $I 1000
  11. done

小结:

    通过以上的脚本编程学习,我想大家应该对脚本编程有了一个初步的了解,希望在以后的学习中能与大家更多的分享脚本编程的知识。
阅读(1296) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~