Shell既是一种命令语言,又是一种程序设计语言(就是你所说的shell脚本)。作为命令语言,它互动式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高阶语言中才具有的控制结构,包括循环和分支。它虽然不是 Linux系统内核的一部分,但它调用了系统内核的大部分功能来执行程序、创建文档并以并行的方式协调各个程序的运行。

我们可以使用任意一种文字编辑器,比如vim  nano  vi等来编写shell脚本,它必须以如下行开始(必须放在文件的第一行):

  1. # !/bin/bash 
  2. … 

符号#!(魔数)用来告诉系统执行该脚本的程序,编辑结束并保存后,如果要执行该脚本,必须先使其可执行:

  1. chmod +x filename 

此后在该脚本所在目录下,输入 ./filename 即可执行该脚本。

或者直接执行bash filename

如果脚本”strangescript”出错,可以使用如下命令进行调试:

sh -x strangescript

7 上述命令会执行该脚本,同时显示所有变量的值。

shell还有一个不执行脚本只检查语法的模式,命令如下:

  1. # sh -n your_script 
  2. #这个命令会返回所有语法错误。

变量赋值和引用


Shell编程中,使用变量无需事先声明,同时变量名的命名须遵循如下规则:

1.             首个字符必须为字母(a-zA-Z

2.             中间不能有空格,可以使用下划线(_

3.             不能使用标点符号

4.             不能使用bash里的关键字(可用help命令查看保留关键字)

需要给变量赋值时可以使用

变量名=变量的值

要取用一个变量的值 ,只需在变量名前面加一个$ ( 注意: 给变量赋值的时候,不能在”=”两边留空格 )

需要注意shell的默认赋值是字符串赋值。比如:

  1. var=1 
  2. var=$var+1 
  3. echo $var 
#打印出来的不是2而是11。为了达到我们想要的效果有以下几种表达方式:
  1. let “var+=1″; 
  2. var=$(($var+1)); 
  3. var=$[$var+1]; 
  4. var=`expr  $var  +  1`;#注意加号两边的空格,否则还是按照字符串的方式赋值。注意:前两种方式在bash下有效,在sh下会出错。 

let表示数学运算,expr用于整数值运算,每一项用空格隔开,$[]将中括号内的表达式作为数学运算先计算结果再输出。

输出时 “” 表示弱引用,如果有变量,先替换变量中的值 ,然后再输出

   ‘’表示强引用,直接引用变量,把变量名输出来

  1. 例如: 
  2. NAME=make 
  3. WHO=$NAME is a boy 
  4. # echo “ $WHO” # 结果为 make is a boy 
  5. # echo ‘$WHO’  # 结果为$NAME is a boy 

 

if 判断语句



“if”表达式如果条件为真,则执行then后的部分:

  1. if ….; then 
  2. …. 
  3. elif ….; then 
  4. …. 
  5. else 
  6. …. 
  7. fi 

大多数情况下,可以使用测试命令来对条件进行测试,比如可以比较字符串、判断文件是否存在及是否可读等等……通常用” [ ] “来表示条件测试,注意这里的空格很重要,要确保方括号前后的空格。

test命令进行条件测试



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

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

1
、条件语句>>test语句

1>
测试字符串间的关系

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

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

  用户可以比较两个字符串相等或不等,也可以测试一个串是否赋了值。有关串的操作符如下:  

  1. str1 = str2      #当两个串有相同内容、长度时为真 
  2. str1 != str2      #当串str1和str2不等时为真 
  3. -n str1         #当串的长度大于0时为真(串非空) 
  4. -z str1         #当串的长度为0时为真(空串) 
  5. str1           #当串str1为非空时为真 

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

  1. $str1=abcd 
  2.    $test $str1 = abcd 
  3.    $echo $? 
  4.    结果显示:0 


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

  1. $str1="abcd " 
  2.    $test "$str1" = abcd 
  3.    $echo $? 
  4.    结果显示:1 

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

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

  1. $str1=abce 
  2.    $test $str1 
  3.    $echo $? 
  4.    结果显示:0     
  5.    $test -n $str1 
  6.    $echo $? 
  7.    结果显示:0 

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

  1. $str1="   " 
  2.    $test $str1 
  3.    $echo $? 
  4.    结果显示:1 
  5.    $test -n "$str1" 
  6.    $echo $? 
  7.    结果显示:0 
  8.    $test -n $str1 
  9.    结果显示:test:argument expected 


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

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

  1. int1 -eq int2    两数相等为真 
  2. int1 -ne int2    两数不等为真 
  3. int1 -gt int2    int1大于int2为真 
  4. int1 -ge int2    int1大于等于int2为真 
  5. int1 -lt int2    int1小于int2为真 
  6. int1 -le int2    int1小于等于int2为真 

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

  1. $str1=1234 
  2.    $str2=01234 
  3.    $test $str1 = $str2 
  4.    $echo $? 
  5.    结果显示:1 
  6.    $test $str1 -eq $str2 
  7.    $echo $? 
  8.    结果显示:0 

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

  1. -r file     用户可读为真 
  2. -w file     用户可写为真 
  3. -x file     用户可执行为真 
  4. -f file     文件为正规文件为真 
  5. -d file     文件为目录为真 
  6. -c file     文件为字符特殊文件为真 
  7. -b file     文件为块特殊文件为真 
  8. -s file     文件大小非0时为真 
  9. -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命令的方法,就是把测试条件放到一对[
]
中,例如:

  1. $int1=4 
  2.    $[ $int1 -gt 2 ] 
  3.    $echo $? 
  4.    结果显示:0 


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

  1.    #-- 备份程序 
  2.    
  3.     #-- 检查参数 
  4.     if [ $# -ne 1 ] 
  5.     then 
  6.       echo "请在程序名后面指出要备份文件所在目录!" 
  7.       exit 1 
  8.     fi 
  9.     #-- 检查目录名是否有效 
  10.     if [ ! -d "$1" ] 
  11.     then 
  12.       echo "$1 不是一个目录!" 
  13.       exit 2 
  14.     fi 
  15.     cd $1 
  16.     ls -a | cpio -o >/dev/mnt0 
  17.     if [ $? -eq 0 ] 
  18.     then 
  19.       rm * 
  20.     else 
  21.       echo "cpio执行不成功!备份失败..." 
  22.       exit 3 
  23.     fi 
  24. 空命令 


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

if语句:

  1. 如果/mnt/cdrom 不存在就创建,如果存在就挂载光盘到该目录。 
  2.  
  3. #!/bin/bash 
  4.  if [-e /mnt/cdrom ]; then 
  5.  mkdir /mnt/cdrom; 
  6.  mount /dev/cdrom  /mnt/cdrom 
  7. fi 

 

&& 和 || 操作符


熟悉C语言的朋友可能会喜欢下面的表达式:

  1. [ -f "/etc/shadow" ] && echo “This computer uses shadow passwords” 

这里的 && 就是一个快捷操作符,如果左边的表达式为真则执行右边的语句,你也可以把它看作逻辑运算里的与操作。上述脚本表示如果/etc/shadow文件存在,则 打印”This computer uses shadow passwords”。同样shell编程中还可以用或操作(||),例如:

  1. #!/bin/bash 
  2.  
  3. mailfolder=/var/spool/mail/james 
  4. [ -r "$mailfolder" ] || { echo “Can not read $mailfolder” ; exit 1; } 
  5. echo “$mailfolder has mail from:” 
  6. grep “^From ” $mailfolder 

该脚本首先判断mailfolder是否可读,如果可读则打印该文件中的”From” 一行。如果不可读则或操作生效,打印错误信息后脚本退出。需要注意的是,这里我们必须使用如下两个命令:

  • -打印错误信息
  • -退出程序

我们使用花括号以匿名函数的形式将两个命令放到一起作为一个命令使用;普通函数稍后再作说明。即使不用与和或操作符,我们也可以用if表达式完成任何事情,但是使用与或操作符会更便利很多 。

case 语句

case表达式可以用来匹配一个给定的字符串,

  1. case … in 
  2. …) comm.;; //以双分号结尾 
  3. esac 

例如 :先打印一个菜单,让用户进行选择,根据用户选择结果显示root 用户对应信息

  1. #! /bin/bash 
  2.  cat << END 
  3.  U|u show uid 
  4.  G|g show gid 
  5.  Q|q quit 
  6.  END 
  7.  read –p “you choice :”CHOICE 
  8.  case $CHOICE in 
  9.  U|u) 
  10. id –u root 
  11. ;;  
  12.  G|g ) 
  13.   id –g root; 
  14.  Q|q ) 
  15.   echo “quit…..” 
  16.    exit 0 
  17.  ;; 
  18. esac 

while/for 循环


shell中,可以使用如下循环:

  1. while …; do 
  2. …. 
  3. done 

只要测试表达式条件为真,则while循环将一直运行。关键字”break”用来跳出循环,而关键字”continue”则可以跳过一个循环的余下部分,直接跳到下一次循环中

  1. #! /bin/bash 
  2. num=0 
  3. while [ $num -le 10 ] 
  4. do 
  5.     num=`expr $num + 1` 
  6.        if [ $num -eq 5 ] 
  7.        then 
  8.               continue   
  9.        fi 
  10.     square=`expr $num \* $num` 
  11.     echo $square 
  12. done 

for循环会查看一个字符串列表(字符串用空格分隔),并将其赋给一个变量:

  1. for var in ….; do 
  2. …. 
  3. done 

下面的示例会把A B C分别打印到屏幕上:

  1. #!/bin/bash 
  2.  
  3. for var in A B C ; do 
  4. echo “var is $var” 
  5. done 
  6.  
  7.   

until


直到条件结束才退出循环

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

  1. #!/bin/bash 
  2. times=0 
  3. until [ "$times" = 3 ]; 
  4. do 
  5.   echo "I love linux." 
  6.   sleep 2 
  7.   times=`expr $times + 1` 
  8. done 

好的,shell脚本就为大家介绍到这里,希望本文能对您学习shell有所帮助。