`
hanxinyu
  • 浏览: 127312 次
  • 来自: henan china
社区版块
存档分类
最新评论

unix 下shell编程(二)

    博客分类:
  • unix
阅读更多
3>在Shell中使用数据变量 

  用户可以在Shell中使用数据变量,例如ba.sh程序: 

    cd/usr/icewalk 
    ls|cpio -o > /dev/fd0 

  该程序中要备份的目录为一常量,即该程序只能用来备份一个目录。若在该程序中使用变量,则会使其更通用: 

    workdir=$1 
    cd $workdir 
    ls * |cpio -o > /dev/fd0 

  通过这一改变,用户可以使用程序备份变量$workdir指定的目录。例如我们要备份/home/www的内容,只要运行ba.sh /home/www即可实现。(若不明白 $1,下面将详细介绍shell参数的传递,$1代表本sh程序-ba.sh的第一个参数) 

  4>在Shell程序中加上注释 

  为了增加程序的可读性,我们提倡加入注释。在Shell程序中注释将以"#"号开始。当Shell解释到"#"时,会认为从"#"号起一直到该行行尾为注释。 

  5>对Shell变量进行算术运算 

  高级语言中变量是具有类型的,即变量将被限制为某一数据类型,如整数或字符类型。Shell变量通常按字符进行存储,为了对Shell变量进行算术运算,必须使用expr命令。 

  expr命令将把一个算术表达式作为参数,通常形式如下: 

    expr [数字] [操作符] [数字] 

  由于Shell是按字符形式存储变量的,所以用户必须保证参加算术运算的操作数必须为数值。下面是有效的算术操作符: 

    +   两个整数相加 
    -   第一个数减去第二个数 
    *   两整数相乘 
    /   第一个整数除以第二个整数 
    %   两整数相除,取余数 
  例如: 
    $expr 2 + 1 
     结果显示:3 
    $expr 5 - 3 
     结果显示:2 

若expr的一个参数是变量,那么在表达式计算之前用变量值替换变量名。 
    $int=3 
    $expr $int + 4 
    结果显示:7 
  用户不能单纯使用"*"做乘法,若输入: 
    $expr 4*5 
  系统将会报错,因为Shell看到"*"将会首先进行文件名替换。正确形式为: 
    $expr 4 \* 5 
     结果显示:20 
  多个算术表达式可以组合在一起,例如: 
    $expr 5 + 7 / 3 
    结果显示:7 
  运算次序是先乘除后加减,若要改变运算次序,必须使用"`"号,如: 
    $int=`expr 5 + 7` 
    $expr $int/3 
     结果显示:4 
    或者: 
    $expr `expr 5+7`/3 
    结果显示:4 

  6>向Shell程序传递参数 

  一个程序可以使用两种方法获得输入数据。一是执行时使用参数。另一种方法是交互式地获得数据。vi编辑程序可以通过交互式的方法获得数据,而ls和expr则从参数中取得数据。以上两种方法Shell程序都可以使用。在"交互式读入数据"一节中将介绍Shell程序通过交互式的方法获得参数。 

  通过命令行给Shell程序传递参数可以扩大程序的用途。以前面提到的ba.sh程序为例: 
  $cat >re.sh 
  cd $workdir 
  cpio -i < /dev/fd0 
  ^d 

  程序re.sh恢复了ba.sh程序备份的所有文件。若只从软盘上恢复一个指定的文件,可以用该文件名作为参数,传递给Shell程序re.sh: 

  程序改写如下: 
  $cat >re2.sh 
  cd $workdir 
  cpio -i $1 < /dev/fd0 
  ^d 

  用户可以指定要恢复的文件,例如fname 

  $re2.sh fname 

此时文件fname作为第一个位置参数传递给re2.sh,re2.sh的缺点是要恢复两个或多个文件要重复运行,我们可以用$*变量传递不确定的参数给程序: 

  $cat >re3.sh 
  cd $workdir 
  cpio -i $* < /dev/fd0 
  ^d 

  我们就可以恢复多个文件,例如fname1,fname2,fname3 
  $re3.sh fname1 fname2 fname3 
  (以上程序re.sh,re2.sh,re3.sh,假设用户已经chmod了可执行权利) 

  因为没有赋值的变量可以作为NULL看待,所以若是程序re3.sh在执行时候没赋予参数,那么一个空值将被插入到cpio命令中。该命令将恢复所有保存的文件。 

条件判断语句 

  条件判断语句是程序设计语言中十分重要的语句,该语句的含义是当某一条件满足时,执行指定的一组命令。 

1>if - then语句 

  格式: if command1 
     then 
       command2 
       command3 
     fi      ---(if 语句结束) 
       command4 

  每个程序或命令执行结束后都有一个返回的状态,用户可以用Shell变量$?获得这一状态。if语句检查前面命令执行的返回状态,若该命令成功执行,那么在then和fi之间的命令都将被执行。在上面的命令序列中,command1和command4总要执行。若command1成功执行,command2和command3也将执行。 

  请看下面程序: 
    #unload -program to backup and remove files 
    cd $1 
    ls -a | cpio -o > /dev/mnt0 
    rm * 

  该程序在备份资料后,删除档案,但当cpio命令不能成功执行时,rm命令还是把资料删除了,我们可不希望这样,为了避免此情况,可以用if - then语句: 
    #--卸载和判断删除程序 

    cd $1 
    if ls -a | cpio > /dev/mnt0 
    then 
      rm * 
    fi 
  上面程序在cpio执行成功后才删除档案 

同时,若执行没有成功,我们希望得到提示,sh中的echo命令可以向用户显示消息,并显示后换行,上面程序可以写成: 
     #--卸载和判断删除程序 
    cd $1 
    if ls -a | cpio > /dev/mnt0 
    then 
      echo "正删除文件资料... ..." 
      rm * 
    fi 

  echo命令可以使用一些特殊的逃逸字符进行格式化输出,下面是这些字符及其含义: 

    \b  Backspace 
    \c  显示后不换行 
    \f  在终端上屏幕的开始处显示 
    \n  换行 
    \r  回车 
    \t  制表符 
    \v  垂直制表符 
    \   反斜框 
    \0nnn 用1,2或3位8进制整数表示一个ASCII码字符 

2>if - then - else语句 

  不用多说它的作用,别的高级语言中都有,格式为: 
  if command1 
  then 
    command2 
    command3 
  else 
    command4 
    command5 
  fi 

  在此结构中,command1中是先执行,当command1成功执行时,将执行command2和command3,否则执行command4和command5 

  注意看下面程序: 
    #备份程序 
    cd $1 
    if ls -a |cpio -o > /dev/mnt0 
    then 
      echo "删除源资料... ..." 
      rm * 
    else 
      echo "磁带备份失败!" 
    fi 

3>test命令进行条件测试 

  if语句可以通过测试命令执行的返回状态来控制命令的执行,若要测试其他条件,在bsh中可以使用test命令。该命令检测某一条件,当条件为真时返回0,否则返回非0值。test命令可以使Shell程序中的if语句象其他程序语言中的条件判断语句一样,具有很强的功能。 

  test命令的使用方法为: 
    test condition 
  可测试的条件分为4类: 
  1)测试两个字符串之间的关系。 
  2)测试两个整数之间关系。 
  3)测试文件是否存在或是否具有某种状态或属性。 
  4)测试多个条件的与(and)或(or)组合。 

1、条件语句>>test语句 

1>测试字符串间的关系 

  bsh把所有的命令行和变量都看作字符串。一些命令如expr和test可以把字符当作数字进行操作。 

  同样任何数字也可以作为字符串进行操作。 

  用户可以比较两个字符串相等或不等,也可以测试一个串是否赋了值。有关串的操作符如下: 
    str1 = str2      当两个串有相同内容、长度时为真 
    str1 != str2      当串str1和str2不等时为真 
    -n str1         当串的长度大于0时为真(串非空) 
    -z str1         当串的长度为0时为真(空串) 
    str1           当串str1为非空时为真 

  不但Shell程序可以使用test进行条件判断,test命令也可以独立执行,如: 

    $str1=abcd 
    $test $str1 = abcd 
    $echo $? 
    结果显示:0 

与上例中第一行赋值语句中的等号不同,test命令中的等号两边必须要有空格。本例test命令共有3个参数。注意两个串相等必须是长度和内容都相等。 

    $str1="abcd " 
    $test "$str1" = abcd 
    $echo $? 
    结果显示:1 

  上面str1包含5个字符,其中最后一个为空格符。而test命令中的另一个串只有4个字符,所以两串不等,test返回1。 

  不带任何操作符和使用-n操作符测试一个串结果是一样的,例如: 

    $str1=abce 
    $test $str1 
    $echo $? 
    结果显示:0     
    $test -n $str1 
    $echo $? 
    结果显示:0 

  但是,上面两条命令也有一点差别,反映出了使用test命令潜在的问题,请看下例: 

    $str1="   " 
    $test $str1 
    $echo $? 
    结果显示:1 
    $test -n "$str1" 
    $echo $? 
    结果显示:0 
    $test -n $str1 
    结果显示:test:argument expected 

  上例中,第一次测试为假因为Shell在执行命令行之前首先要进行变量替换,即把$str1换成空格,然后shell又将命令行上的空格删除,故test命令测试到的为空串。而在第二次测试中,变量替换后空格位于括号内,故不会被删除,test测试到的是一个包含空格的串,在第三次测试中,shell把空格删除,只把-n传个test命令,所以显示参数错。 

2>测试两个整数之间关系 

  test命令与expr命令一样,也可以把字符转变成整数,然后对其操作。test命令对两个数进行比较,使用的操作符如下: 

    int1 -eq int2    两数相等为真 
    int1 -ne int2    两数不等为真 
    int1 -gt int2    int1大于int2为真 
    int1 -ge int2    int1大于等于int2为真 
    int1 -lt int2    int1小于int2为真 
    int1 -le int2    int1小于等于int2为真 

  下面的例子反映了字符串比较与数字比较的不同: 

    $str1=1234 
    $str2=01234 
    $test $str1 = $str2 
    $echo $? 
    结果显示:1 
    $test $str1 -eq $str2 
    $echo $? 
    结果显示:0 

3>有关文件的测试 

  使用test进行的第三类测试是测试文件的状态,用户可以测试文件是否存在,是否可写以及其他文件属性。下面是文件测试时使用的选项。注意只有文件存在时,才有可能为真。 

  -r file     用户可读为真 
  -w file     用户可写为真 
  -x file     用户可执行为真 
  -f file     文件为正规文件为真 
  -d file     文件为目录为真 
  -c file     文件为字符特殊文件为真 
  -b file     文件为块特殊文件为真 
  -s file     文件大小非0时为真 
  -t file     当文件描述符(默认为1)指定的设备为终端时为真 
4>复杂的条件测试(and 、or 、not) 
  -a         与 
  -o        或 
  !        非 
  就是组合条件了,任何高级语言中都有的(NOT 、AND 、OR),例如: 
    $test -r em.null -a -s em.null 
    $echo $? 
    结果显示:1 
    说明了em.null并不是可读并且非空的文件 

5>另一种执行test的方法 

  bsh中还有另一种执行test命令的方法,就是把测试条件放到一对[ ]中,例如: 
    $int1=4 
    $[ $int1 -gt 2 ] 
    $echo $? 
    结果显示:0 

要注意在[ 的后面和 ]符号的前面要有一个空格。 
  下面我们用test命令写个简单但比较完善的程序: 

    #-- 备份程序 
   
    #-- 检查参数 
    if [ $# -ne 1 ] 
    then 

      echo "请在程序名后面指出要备份文件所在目录!" 
      exit 1 
    fi 
    #-- 检查目录名是否有效 
    if [ !-d "$1" ] 
    then 
      echo "$1 不是一个目录!" 
      exit 2 
    fi 
    cd $1 
    ls -a | cpio -o >/dev/mnt0 
    if [ $? -eq 0 ] 
    then 
      rm * 
    else 
      echo "cpio执行不成功!备份失败..." 
      exit 3 
    fi 

6>空命令 

  在Bsh中用 : 代表空命令,就是充个数,什么都不做 

7>嵌套if语句和elif结构 

  检查条件1 
  A:当条件1为真,则执行一部分操作 
  B:若条件1为假,检查条件2 
    1)若条件2为真,执行另外一部分操作 
    2)若条件2为假,检查条件3 
    3)若条件3为真,执行其他一部分操作 
  语法如下: 
    if command 
    then 
      command 
    else 
      if command 
      then 
        command 
      else 
        if command 
        then 
          command 
        fi 
      fi 
    fi 

8>elif语句 

  嵌套if语句有时会给用户带来混乱,特别是什么时候fi语句很难判断。因此Bourne Shell又提供了elif语句。elif是else-if的缩写,它表示是if语句的继续。格式为: 

    if command 
    then 
      command 
    elif command 
    then 
      command 
    elif command 
    then 
      command 
    fi 

  上面介绍的嵌套if语句和elif语句完成相同的功能,用户可以根据自己的喜好选择一种使用。 

9>case语句 

  前面说的elif语句替代if-then-else语句,但有时在编程时还会遇到对同一变量进行多次的测试,该情况可以用多个elif语句实现,但还有一种更简单的方法就是用case语句。 

  case语句不但取代了多个elif和then语句,还可以用变量值对多个模式进行匹配,当某个模式与变量值匹配后,其后的一系列命令将被执行,下面是case语句使用的语句。 

  case value in 
   pattem 1) 
    command 
    command;; 
   pattem 2) 
    command 
    command;; 
   .... 
   pattem) 
    command; 
  esac 

  case语句只执行其中的一组命令,当变量值与多个模式相匹配时,只有第一个匹配的模式对应的命令被执行。";;"表示该模式对应的命令部分程序。 

  通过学习下面的read语句,我们们再举例子说明case语句的用法。 

10>read语句 

  Shell程序不但可以通过命令行参数得到输入数据,还可以使用read命令提示用户输入数据,其语法格式为: 

  read var1 var2... ...varn 

当Bsh遇到一个read语句时,在标准输入文件中读取数据直到一个换行符。此时Shell在解释输入行时,不进行文件名或变量的替换,只是简单地删除多余的空格。然后Shell将输入行的第一个字的内容给变量1,第二个给变量2,直到所有变量都赋上值或是输入行为空。若输入行中字的个数超过变量个数,Shell将把输入行中剩余的所有字的内容都赋给最后一个变量。当变量个数多于输入行字的个数时候,多于的变量将赋一个空值。输入行的每一个字是由空格分隔的一个字母和数字组成的字符串。 

  $read var1 var2 var3 
    输入:Hello my friend 
   
  $echo $var1 $var2 $var3 
    结果显示:Hello my friend 
  $echo $var2 
    结果显示:my 

下面用个read和case的例子结束本部分的学习: 

  #--交互式备份,恢复程序 
  echo "输入要备份文件所在目录:\c" 
  read WORKDIR 
  if [ !-d $WORKDIR ] 
  then 
    echo "Sorry,$WORKDIR is not a directory" 
    exit 1 
  fi 
  cd $WORKDIR 
  echo "输入选择:" 
  echo _ 
  echo "1.恢复到 $WORKDIR" 
  echo "2.备份 $WORKDIR" 
  echo "0.退出" 
  echo 
  echo "\c" 
  read CHOICE 
  case "$CHOICE" in 
   1)echo "恢复中... ..." 
    cpio -i < /dev/mnt0;; 
   2)echo "备份中... ..." 
    ls | cpio -o > /dev/mnt0;; 
   0)exit 1 
   *)exit 1 
  esac 
  if [ $? -ne 0 ] 
  then 
   echo "程序运行中出现错误!" 
  else 
   echo "操作成功!" 
fi   
  
  在上面代码中,"*"定义了其他模式下不匹配时的默认操作。 

循环语句 

  前面介绍的程序和所学的语句都是从头到尾成一条主线下来,或是成分支结构,在日常管理UNIX的过程中,经常要重复的做一些操作,处理批量的问题,这就涉及到了循环结构,同高级语言相似,UNIX的Shell也提供了强大的循环处理语句。 

  Bsh语言中有三种循环语句-while循环、until循环、for循环,下面通过具体的例子分别介绍这三种结构。 

While循环 

  在while循环语句中,当某一条件为真时,执行指定的命令。语句的结构如下: 

while command 
do 
  command 
  command 
  … … 
done 

示例代码如下: 

#测试while循环小程序 

x_t=1 
  while [  $x_t -lt 5 ] 
  do 
     mm=` expr $x_t \* $int `  #注意"\"的作用 
     echo "$mm" 
     x_t=` expr $x_t + 1 `   #注意expr的用法 
  done 
  echo "THE WHILE IS END!\n" 

程序的执行结果如下: 



16 
THE WHILE IS END 

  在上述程序中,当变量x_t的值小于5的时候,执行while循环中的语句。在第五次循环时, [ $x_t-lt5]命令返回非零值,于是程序执行done后面的代码。 
现在利用while循环,可以改进我们早些时候用的备份数据的例子,当用户指定的目录备份完毕后,使用while循环使程序执行一次可以备份多个用户指定的目录。代码如下: 

echo "欢迎使用备份小程序" 

  ANS=Y 
  while [ $ANS = Y -o $ANS = y ] 
  do 
    echo _ 
    #读目录名 
    echo "输入要备份的目录名:\c" 
    read DIR 
    if [ ! -d $DIR ] 
    then 
        echo "$DIR不是一个目录!" 
        exit 1 
    fi 
    cd $DIR 
    echo "请选择:" 
    echo _ 
    echo "1 恢复数据到 $DIR" 
    echo "2 备份$DIR的数据" 
    echo 
    echo "请选择:\c" 
    read CHOICE 
    case "$CHOICE" in 
       1) echo "恢复中… …" 
        cpio -i        2) echo "备份中… …" 
        cpio -o >/dev/rmt0;; 
       *) echo "选择无效" 
    esac 
    if [ $? -ne 0 ] 
    then 
       echo "cpio执行过程中出现问题" 
       exit 2 
    fi 
    echo "继续别的目录吗?(Y/y)\c" 
    read ANS 
  done 

  在程序开始,我们给变量ANS符值为Y,根据whlie的判断条件,程序进入while循环,执行do-done中的语句,每次循环都要求用户输入ANS的值用来判断是否进行下次重复执行do-done中的语句。如果用户输入的条件不满足while语句条件,循环结束,程序执行done后面的语句。 
分享到:
评论

相关推荐

    Linux与UNIX Shell编程指南.pdf

    Linux与UNIX Shell编程指南是计算机科学领域中一本经典的指南手册,旨在帮助读者快速掌握Linux与UNIX操作系统下的shell编程技术。下面是从该书中生成的相关知识点: 1. Shell概述 Shell是Linux与UNIX操作系统下的...

    shell编程入门教程+shell脚本专家指南+UNIX.shell编程24小时教程.rar

    Shell编程是Linux/Unix操作系统中的一种重要工具,它允许用户通过命令行与系统进行交互,执行各种任务。本文将深入探讨Shell编程的基础知识,包括基本语法、常用的内置命令、条件语句、循环结构以及函数的使用,旨在...

    Unix Shell Shell编程

    6本pdf及chm的shell 编程的书 6本pdf及chm的shell 编程的书 6本pdf及chm的shell 编程的书 6本pdf及chm的shell 编程的书 6本pdf及chm的shell 编程的书

    LINUX与UNIX SHELL编程指南.rar

    LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 LINUX UNIX SHELL 编程 ...

    UNIX.Shell编程24学时教程.pdf

    第二部分是本书的核心,详细介绍了如何使用Shell编程。在这里,读者将学习到Shell编程中所涉及的所有工具和技巧。最后一部分探讨了Shell编程中较为高级的主题,帮助读者解决编程实践中可能遇到的问题。为便于读者...

    linux与unix_shell编程指南

    《Linux与Unix Shell编程指南》是一本专注于操作系统交互和脚本编写的重要教程。在Linux和Unix系统中,Shell是用户与操作...通过学习这本书,读者将能够掌握Shell编程的核心技能,提升在Linux和Unix环境下的工作效率。

    shell编程入门经典--LINUX与UNIX Shell编程指南 (中文pdf版)

    《LINUX与UNIX Shell编程指南》是一本专为初学者设计的shell编程教程,它深入浅出地介绍了在Linux和UNIX系统中如何使用Shell进行高效自动化任务处理。Shell编程是Linux和UNIX系统中的核心技术,它允许用户通过命令行...

    UNIX命令及SHELL编程

    这是一套完整的Unix培训教材,包括Unix常用命令及SHELL编程基础与高级技巧,PDF格式,共30个文件。另有2个Word文档。包内文件清单如下: 01_Shell-文件安全与权限.PDF 02_Shell-使用find和xargs.PDF 03_Shell-...

    UNIX shell语言编程24小时学会

    第二部分(学时7-12)是本书的核心内容,专门介绍如何使用Shell编程。这一部分将为读者详细讲解在Shell编程中可能会用到的各种工具,包括决策、循环执行命令、创建函数以及变量的使用等。在这一部分中,读者将学会...

    绝版经典 LINUX与UNIX SHELL编程指南 PDF 高清版 [16.3M]

    本书共分五部分 ,详细介绍了SHELL编程技巧,各种UNIX命令及语法,还涉及了UNIX的文字处理以及少量的系统管理问题。本书内容全面,文字简洁流畅,适合SHELL编程人员学习、参考。 目录 第一部分 SHELL 第一章 文件...

    UNIX_SHELL编程课程讲义

    UNIX_SHELL编程课程讲义 包括UNIX虚拟机的安装使用、CRT使用、UItraEdit工具使用、shell的概述、shell变量、shell控制结构、shell函数、shell script编程实例

    《LINUX与UNIX SHELL编程指南》读书笔记-二次发布版

    本文将基于《LINUX与UNIX SHELL编程指南》这本书的读书笔记,深入探讨Linux与Unix Shell编程的核心知识点。 一、Shell概述 Shell是一个命令解释器,它接收用户输入的命令并执行。在Linux和Unix系统中,常见的Shell...

    Unix.Shell编程(第三版).zip

    《Unix Shell编程(第三版)》是一本深入探讨Unix Shell编程技术的专业书籍,适用于那些希望在Unix或类Unix操作系统环境中提升自动化任务处理能力的读者。Shell编程是Unix系统中的核心功能之一,它允许用户通过编写...

    unix shell编程第三版笔记

    在IT领域,Unix Shell编程是一种极其重要的技能,尤其对于系统管理员和开发者来说。"Unix Shell编程第三版笔记"是铁道出版社出版的一本教材,它深入浅出地讲解了Unix Shell编程的基础和高级技巧。这份笔记涵盖了从...

    UNIX.Shell编程24学时教程

    UNIX.Shell编程24学时教程,学习linux shell必备工具书。

    用Linux/UNIX Shell编程语言设计系统监控程序.pdf

    "Linux/UNIX Shell编程语言设计系统监控程序.pdf" 本文档主要介绍了使用Linux/UNIX Shell编程语言设计系统监控程序的方法。该程序使用Shell编程语言设计CGI脚本,通过使用过滤器awk在某些输出行中提取信息,然后在...

Global site tag (gtag.js) - Google Analytics