shall脚本基础(一)

一、shell脚本变量

1)shell脚本的基础知识
    (1)shell脚本的本质
     编译型语言
     解释型语言
        shell脚本语言是解释型语言
        shell脚本的本质
            shell命令的有序集合
    (2)shell 编程的基本过程
     基本过程分为三步:
     step1. 建立 shell 文件
               包含任意多行操作系统命令或shell命令的文本文件;
     step2. 赋予shell文件执行权限
             用chmod命令修改权限;
     step3. 执行shell文件
               直接在命令行上调用shell程序.
    (3)实例
     step1: 建立shell文件 (可用任何建立文本文件的方法)
             $ cat  prog1.sh
               date
     Step2: 赋予执行权限:  (初始文本文件无执行权限)
              $ chmod  740  prog1.sh
     Step3: 执行该shell程序
                 $ prog1.sh
                    prog1.sh: not found    
                  (shell在标准搜索路径中找不到prog1.sh)
     Step4: 指定路径或修改环境变量PATH后执行shell程序
              $ ./prog1.sh  
              2009年  12月  16日  星期二  14:52:57  CST

2)shell变量
    (1)shell变量
     shell允许用户建立变量存储数据,但不支持数据类型(整型、字符、浮点型),
     将任何赋给变量的值都解释为一串字符

                        Variable=value
     a.   count=1
     b.   echo $count
     c.   DATE=`date`
     d.   echo $DATE


     (2) Bourne Shell有如下四种变量:
        1) 用户自定义变量 
        2) 位置变量即命令行参数 
          3) 预定义变量 
        4) 环境变量
     (3) 用户自定义变量
     1) 在shell编程中通常使用全大写变量,方便识别 
        $ COUNT=1
     2) 变量的调用:在变量前加$ 
        $ echo $HOME 
     3) Linux Shell/bash从右向左赋值
        $Y=y
        $ X=$Y
        $ echo $X 
        y     
     4) 使用unset命令删除变量的赋值 
        $ Z=hello 
        $ echo $Z 
        hello 
        $ unset Z 
        $ echo $Z 
     (4) 位置变量

     $0   与键入的命令行一样,包含脚本文件名
     $1,$2,……$9  分别包含第一个到第九个命令行参数
     $#   包含命令行参数的个数
     $@   包含所有命令行参数:“$1,$2,……$9”
     $?   包含前一个命令的退出状态
     $*   包含所有命令行参数:“$1,$2,……$9”
     $$   包含正在执行进程的ID号


     (5) 常用shell环境变量 
     HOME: /etc/passwd文件中列出的用户主目录 
     IFS:Internal Field Separator, 默认为空格,tab及换行符
     PATH :shell搜索路径
     PS1,PS2:默认提示符($)及换行提示符(>) 
     TERM:终端类型,常用的有vt100,ansi,vt200,xterm等 

 二、功能语句

 

1)说明性语句
    (1)shell 程序和语句
     shell 程序由零或多条shell语句构成。 shell语句包括三类:说明性语句、功能性语句和结构性语句。
     说明性语句:
        以#号开始到该行结束,不被解释执行
     功能性语句: 
        任意的shell命令、用户程序或其它shell程序。
     结构性语句:
        条件测试语句、多路分支语句、循环语句、循环控制语句等。             
    (2)说明性语句(注释行)
        注释行可以出现在程序中的任何位置,既可以单独占用一行,  也可以接在执行语句的后面. 
     以#号开始到所在行的行尾部分,都不被解释执行. 例如:
        #! /bin/sh 
        #         ------> 告诉OS用哪种类型的shell来解释执行该程序
        # 本程序说明
        #
        command_1 
        command_2                  # command_2的语句说明
        ……
        # 下面程序段的说明
        command_m
        ……
        command_n                  # commandn_语句的说明
        ……

2)常用功能性语句
     (1) 常用功能性语句(命令)
    read从标准输入读入一行, 并赋值给后面的变量,其语法为:
               read  var
        把读入的数据全部赋给var
              read  var1  var2  var3
        把读入行中的第一个单词(word)赋给var1, 第二个单词赋给var2, ……把其余所有的词赋给最后一个变量.
    如果执行read语句时标准输入无数据, 则程序在此停留等侯, 直到数据的到来或被终止运行。
     (2) 应用实例

     # example1  for  read
     echo  "Input  your  name: \c"
     read  username
     echo  "Your name is  $username"     #example2  for  read
     echo "Input  date  with  format  yyyy  mm dd: \c"
     read  year  month  day
     echo  "Today  is  $year/$month/$day,  right?"
     echo  "Press  enter  to  confirm  and  continue\c"
     read  answer
     echo "I  know  the  date,  bye!"


     (3) expr命令
     算术运算命令expr主要用于进行简单的整数运算,包括加(+)、减(-)、乘(\*)、整除(/)和求模(%)等操作。
     例如:

$ expr  12  +  5  \*  3            反斜线去掉*号的元字符含义
  27
$ expr  3  -  8  /  2
          -1

$ num=9
$ sum=`expr  $num  \*  6 `          反撇号引用命令的运行结果

$ echo  $sum
54


3)测试语句
     (1)test语句
    test语句可测试三种对象:
              字符串     整数     文件属性
     (2)每种测试对象都有若干测试操作符
    例如:
              test  "$answer"  =  "yes"
              变量answer的值是否为字符串yes
              test  $num –eq  18
              变量num的值是否为整数18
              test  -d  tmp    
              测试tmp是否为一个目录名
     (3) 字符串测试

     s1 = s2     测试两个字符串的内容是否完全一样
     s1 != s2    测试两个字符串的内容是否有差异
     -z s1     测试s1 字符串的长度是否为0
     -n s1     测试s1 字符串的长度是否不为0


     (4) 整数测试

     a -eq b         测试a 与b 是否相等
     a -ne b        测试a 与b 是否不相等
     a -gt b         测试a 是否大于b
     a -ge b         测试a 是否大于等于b
     a -lt b         测试a 是否小于b
     a -le b         测试a 是否小于等于b


     (5) 文件测试
 

     -d name    测试name 是否为一个目录
     -e name    测试一个文件是否存在
     -f name    测试name 是否为普通文件
     -L name    测试name 是否为符号链接
     -r name    测试name 文件是否存在且为可读
     -w name    测试name 文件是否存在且为可写
     -x name    测试name 文件是否存在且为可执行
     -s name    测试name 文件是否存在且其长度不为0
     f1 -nt f2  测试文件f1 是否比文件f2 更新
     f1 -ot f2  测试文件f1 是否比文件f2 更旧

三、 分支语句

 

1)条件语句
    (1)结构性语句
     结构性语句主要根据程序的运行状态、输入数据、变量的取值、控制信号以及运行时间等因素来控制程序的运行流程。
     主要包括:条件测试语句(两路分支)、多路分支语句、循环语句、循环控制语句和后台执行语句等。
    (2)条件语句
     if…then…fi
     语法结构:
                      if    表达式
                          then  命令表
                 fi     
    1)如果表达式为真, 则执行命令表中的命令; 否则退出if语句, 即执行fi后面的语句。 
    2)if和fi是条件语句的语句括号, 必须成对使用;
    3)命令表中的命令可以是一条, 也可以是若干条。
    (3)复习-文件测试

        -d name    测试name 是否为一个目录
        -e name    测试一个文件是否存在
        -f name    测试name 是否为普通文件
        -L name    测试name 是否为符号链接
        -r name    测试name 文件是否存在且为可读    
        -w name    测试name 文件是否存在且为可写
        -x name    测试name 文件是否存在且为可执行
        -s name    测试name 文件是否存在且其长度不为0
        f1 -nt f2  测试文件f1 是否比文件f2 更新
        f1 -ot f2  测试文件f1 是否比文件f2 更旧


    (4)实例
    shell程序prog2.sh(测试命令行参数是否为已存在的文件或目录)。用法为:
          ./prog2.sh   file

    代码如下:  

#The statement of  if…then…fi                 (注释语句)
if   [  -f   $1  ]         (测试参数是否为文件)
then
    echo "File  $1  exists"                     (引用变量值)
fi
if   [  -d   $HOME/$1  ]                    (测试参数是否为目录)
then 
    echo "File  $1 is  a  directory"       (引用变量值)
fi


    执行prog2程序:
        $ ./prog2.sh   prog1.sh
        File  prog1.sh exists
                  $0为prog2.sh;  $1为prog1.sh, 是一个已存在的文件.
        $ ./prog2.sh   backup
        File  backup is  a directory
                       $0为prog2.sh;  $1为backup,是一个已存在的目录.
    如果不带参数, 或大于一个参数运行prog2, 例如:
    $  ./prog2.sh      (或 $ ./prog2.sh  file1  file2)
    会出现什么结果?
    (5) if…then…else…fi
      语法结构为:
             if      表达式
                  then 命令表1
             else  命令表2
             fi
     如果表达式为真, 则执行命令表1中的命令, 再退出if语句; 否则执行命令表2中的语句, 再退出if语句.
     注意: 无论表达式是否为真, 都有语句要执行.
    (6)test命令的使用
     test命令测试的条件成立时, 命令返回值为真(0),否则返回值为假(非0).
     方式一:
        test   $name  -eq   $1
        echo  $?
     方式二:
        if   test   -f   $filename
        then 
             ……
        fi
     方式三:
        if  [   -f  $filename  ]
        then 
             ……
        fi
        用方括号替代test语句,注意方括号前后至少有一个空格
    (7)实例
     例子:    shell程序prog3.sh,  用法为:
                       ./prog3.sh   file
     内容如下:

#The statement of if…then…else…fi
if   [  -d  $1  ]
then
    echo "$1  is  a  directory"
    exit          (退出当前的shell程序)
else 
    if  [  -f   $1  ]
    then
        echo  "$1  is  a  common  file"
    else
        echo  "unknown"  
    fi
fi


     运行prog3.sh程序:
     $ ./prog3.sh  backup
     backup  is  a  directory

     $ ./prog3.sh  prog1
     prog1  is  a  common  file

     $ ./prog3.sh  abc
     unknown
      prog3.sh是对prog2.sh的优化, 逻辑结构更加清晰合理!

2)多路分支语句
    (1)多路分支语句 
     case…esac 
            多路分支语句case用于多重条件测试, 语法结构清晰自然.  其语法为:
             case   字符串变量   in
                    模式1)
                               命令表1
                            ;;
                    模式2 | 模式3)   
                               命令表2
                            ;;
                     ……
                    模式n)
                               命令表n
                            ;;
            esac
    注:
       1)case语句只能检测字符串变量
       2)各模式中可用文件名元字符,以右括号结束
       3)一次可以匹配多个模式用“|”分开
       4)命令表以单独的双分号行结束,退出case语句
       5)模式 n常写为字符* 表示所有其它模式
       6)最后一个双分号行可以省略
    (2)实例
     实例.  程序prog4.sh检查用户输入的文件名, 用法为:
                   ./prog4.sh    string_name

# The statement of  case…esac
if   [  $#  -eq  0  ]
then
    echo  "No argument is declared"
    exit
fi
    case  $1  in
        file1)
             echo  "User selects file1"
             ;;
        file2)
             echo  "User selects file2"
             ;;
         *)
             echo  "You must select either file1 or file2!"
             ;;
     esac


 

 四、循环语句

 

1)循环语句for的用法
    (1)循环语句for
     1)当循环次数已知或确定时,使用for循环语句来多次执行一条或一组命令。 
        循环体由语句括号do和done来限定。格式为:                
         for   变量名   in   单词表
                  do
                          命令表
                       done
     2)变量依次取单词表中的各个单词,  每取一次单词, 就执行一次循环体中的命令.  
        循环次数由单词表中的单词数确定. 命令表中的命令可以是一条, 也可以是由分号或换行符分开的多条。
         3)如果单词表是命令行上的所有位置参数时, 可以在for语句中省略 “in  单词表” 部分。
    (2)实例
     实例:程序prog5.sh拷贝当前目录下的所有文件到backup子目录下.  
     使用语法为:  ./prog5.sh    [filename] 

    # The statement of for…do…done
    if  [  !  -d  $HOME/backup  ]
    then
        mkdir  $HOME/backup
    fi
    flist=`ls`
    for  file  in  $flist
    do
        if   [  $#  =  1  ]
        then
            if   [  $1  =  $file  ]
            then
                echo  "$file  found" ;  exit
            fi
        else
            cp  $file  $HOME/backup
            echo  "$file  copied"
        fi
    done
    echo   ***Backup  Completed***


2)循环语句while的用法
    (1)语法结构为:
                  while    命令或表达式
                        do
                           命令表
                        done
    1)while语句首先测试其后的命令或表达式的值,如果为真,就执行一次循环体中的命令,
       然后再测试该命令或表达式的值,执行循环体,直到该命令或表达式为假时退出循环。
    2)while语句的退出状态为命令表中被执行的最后一条命令的退出状态。
   (2)实例
    创建文件程序prog6,  批量生成空白文件,用法为:
                      prog6   file   [number]  ./a.sh file  6
  

 # The statement for  while
    if [ $# = 2 ]
    then
            loop=$2        ------>根据命令行的第二个参数来确定循环的次数
    else
            loop=5
    fi
    i=1
    while  [  $i  -lt   $loop  ]
    do
            > $1$i         ------> 建立以第一个参数指定的文件名前缀,
                           例如以“file”开头, 变量i的值结尾的空文件名. 参见命令cmd  >  file
            i=`expr  $i  +  1`
    done


3)循环控制语句
     (1) break 和 continue 
          break  n  则跳出n层;  
        continue语句则马上转到最近一层循环语句的下一轮循环上,  
         continue  n则转到最近n层循环语句的下一轮循环上.

    实例.  程序prog7的用法为:

    #                  prog7   整数   整数   整数 …
    #参数个数不确定, 范围为1~10个, 每个参数都是正整数。
     if  [  $#  =  0  ]
     then
        echo  "Numeric  arguments  required"
        exit
     fi
     if  [  $#  -gt   10  ]
     then
        echo  "Only  ten  arguments  allowed"
        exit
     fi
     for  number
     do
        count=`expr  $number  %  2`
        if  [  $count  -eq  1  ]
        then
            continue
        else
            output="$output   $number"
        fi
     done
     echo  "Even  numbers:  $output "

 五、函数

 

1)shell函数调用
    (1)函数调用格式:
     方式1:
         value_name=`function_name  [arg1 arg2 … ]`
     函数的所有标准输出都传递给了主程序的变量
     方式2:
        function_name  [arg1  arg2  …  ]
        echo   $?
    获取函数的返回的状态
     (2) 实例

    check_user( )    {  #查找已登录的指定用户
          user=`who  |  grep  $1 | wc -l`
            if [ $user –eq 0 ]
                then
                       return  0       #未找到指定用户
            else
                          return  1       #找到指定用户
            fi
    }
    while  true         # MAIN, Main, main:   program  begin  here
    do
        echo  "Input username: \c"
        read   uname
        check_user  $uname       # 调用函数, 并传递参数uname
        if [ $? –eq  1 ]                 # $?为函数返回值
        then    echo  "user  $uname  online"
        else    echo  "user  $uname  offline"
        fi
    done


2)函数变量作用域 
    (1)全局作用域:在脚本的其他任何地方都能够访问该变量。
    (2)局部作用域:只能在声明变量的作用域内访问。
    (3)声明局部变量的格式:
            Local   variable_name =value    (4) 
 

    Scope()
    {    
    Local lclvariable =1
    Gblvariable = 2
    echo “lclavariable in function = $ lclvariable ”
    echo “Gblvariable in function = $ Gblvariable ”
    }

    Scope

    echo “lclavariable in function = $ lclvariable ”
    echo “Gblvariable in function = $ Gblvariable ”

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一天干五顿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值