Shell脚本编程知识点总结及范例

 一:关于语言

   1)编译性语言

       编译型语言多半运作于底层,所处理的是字节、整数、浮点数或其它及其机器层经的对象。处理过程为:源程序--预处理--编译--汇编--链接,编译性语言为静态语言。

   2)解释性语言

        解释性语言读入程序代码并将其转化为内部的形式加以执行。处理过程:解释性(文本文件)-解释器去读取并执行。解释性语言为动态语言。

二:基础

     变量类型

       linux脚本中的变量不需要事先声明,而是直接定义使用(这点不同于其他高级编程语言中变量的使用)bash变量类型分为本地变量和环境变量。

   本地变量:只对当前的shell有效,对其他shell及其子shell没效

   环境变量:对当前shell进程及其子shell有效,对其它的shell进程无效。

   位置变量:$1, $2, ..., ${10};$1为第一个输入的变量$0为函数的本身,

   特殊变量:$?

   特殊变量:$#和$@为总共输入变量的数量。  取用户输入参数的个数

   特殊变量:$*表示所有这些参数都被双引号引住。若一个脚本接收两个参数,$*等于$1$2;$@表示所有这些参数都分别被双引号引住

   变量的引用  " ":弱引用,里面的变量会被替换;

               ' ':强引用,里面的所有字符都是字面量,直接输出.


   自定义shell的状态返回值

     exit [n]


   自定义一个数的值

     declare -i a=0

   数值运算

     let num++  每成功执行一次自动添加一次。

   交互式编程

      read  -p "输入说明: "  a

            -t :超时结束

     read -p "PLZ inpit you name: " -t 3  :请输入用户名,超时3秒结束输入。


   变量的赋值

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

      1)首个字符必须为字母(a-z,A-Z)

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

      3)不能使用标点符号

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

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

       变量的赋值:var_name=var_value  

       显示变量的值使用:echo $var_name

wKiom1PdpJnyhppXAACuYNvp0rU257.jpg

      另外我们可以将一个命令的的执行结果赋值给一个变量

wKioL1PdpgXy1_XAAABS-aylj94631.jpg

三:shell中括号的用法


    1)符号$后的括号
      ${a} 变量a的值, 在不引起歧义的情况下可以省略大括号。
      $(cmd) 命令替换, 结果为shell命令cmd的输出, 和`cmd`效果相同, 不过某些Shell版本不支持$()形式的命令替换, 如tcsh。
      $((exp)) 和`expr exp`效果相同, 计算数学表达式exp的数值, 其中exp只要符合C语言的运算规则即可, 甚至三目运算符和逻辑表达式都可以计算。

    2)多条命令执行

(cmd1;cmd2;cmd3) 新开一个子shell顺序执行命令cmd1,cmd2,cmd3, 各命令之间用分号隔开, 最后一个命令后可以没有分号。


{ cmd1;cmd2;cmd3;} 在当前shell顺序执行命令cmd1,cmd2,cmd3, 各命令之间用分号隔开, 最后一个命令后必须有分号, 第一条命令和左括号之间必须用空格隔开。


对{}和()而言, 括号中的重定向符只影响该条命令, 而括号外的重定向符影响到括号中的所有命令。

    3)双括号的特殊用

(()) 增强括号的用法, 常用于算术运算比较. 双括号中的变量可以不使用$符号前缀, 只要括号中的表达式符合C语言运算规则, 支持多个表达式用逗号分开。比如可以直接使用for((i=0;i<5;i++)), 如果不使用双括号, 则为for i in `seq 0 4`或者for i in {0..4},再如可以直接使用if (($i<5)), 如果使用中括号, 则为if [ $i -lt 5 ].


[[]] 增强方括号用法, 常用于字符串的比较. 主要用于条件测试, 双括号中的表达式可以使用&&, ||, <, >等C语言语法。比如可以直接使用if [[ $a -ne 1 && $a -ne 2 ]], 如果不使用双括号, 则为if [ $a -ne 1] && [ $a -ne 2 ]或者if [ $a -ne 1 -a $a -ne 2 ].


四:命令的逻辑关系

   1)逻辑与&&

    command1&&command2

    command1为真是执行command2;为假时不在执行command2

   2)逻辑||

    command1||command2

    command1为假时执行command2;为真时不执行执行command2

   3)逻辑非!

     !command

     比命令的执行结果取反 

  例:

 

wKioL1PdqofhMz_BAAGD32_jQYw943.jpg

五:条件测试


    1)文件类型测试

      判断文件的存在性及属性

      [ -e filename ] :文件存在则为真。

      [ -f file ]:文件存在且是一个普通文件。 

      [ -d directory ]:存在并且为目录文件。

      [ -b block ]:存在且是一个快设备。

      [ -L Filer]:存在且是一个符号连接文件。

      [ -s Filer]:存在且是一个非空文件。

    

     2)文件的执行权限

      [ -r filename ]:存在可读权限

      [ -w filename ]:存在可写权限

      [ -x filename ]:存在可执行权限

      [ -N filename ]:最后一次修改时间比最近一次访问时间距现在时间还近。

      [ file1 -nt file2 ]:file1最后一次修改时间比file2还要新则为真。

      [ file1 -ot file2 ]:file1旧于file2为真

       

      [[ express ]] (代表关键字)


       3)整数测试

       比较两个数谁大谁小。

          关于整数测试的符号有:

        -gt(大于)      -ge(大于等于)

              -lt(小于)          -le(小于等于)

              -eq(等于)    -ne(不等于)

      整数测试需要放在[ ]中且括号内两边和数字之间及等号与数字之间要有空格

               >; <; >=; <=; =; !=

      要放在(( ))进行比较。

    4)字符串测试

       字符串比较

         =  等于,如:if [[ "$a" = "$b" ]];   ==  等于,如:if [[ "$a" == "$b" ]],与=等价

       字符串要有引号,且字符串两边要有空格。引用变量时要有双引号

     双目操作符

         >(大于)  ;<(小于) ;!=(不等于)   =(等于)

     模式匹配

       [[ "$var" =~ PATTERN ]]


     单目操作符

         -z "string"  测试string字符串是否为空 .空为真

          -n "string"   测试string字符串是否不为空 .不空为真

         条件测试一般要用[[  ]] 

     注意比较运算只在同一中类型进行比较

六:组合条件测试

     与: [ condition1 -a condition2 ]

          两个都满足即可生效

     或:  [ conditionl -o condition2 ]

          满足其中一个条件即可生效

     非:  [ -not condition ]

如果不用中括号的话

     与:condition1 && condition2

     或:condition1 || condition2

     非:!condition

 ![ a -o b ] = [ !a -a !b ]

 ![ a -a b ] = [ !a -o !b ]




六:算数运算


         1)  let sum=$n1+$n2

       2)  sum=$[$n1+$n2]  $[ ]只能进行整数运算

       3)  expr   1 + 2

       4)  num=$((1+2))

wKioL1PduVWBNiJJAAIpb5_oTag943.jpg

七:shell脚本中的控制语句


   1)if选择语句

 单分支语句                           双分支语句                      多分支语句

  1. if 测试条件;then             if 条件;then              if 条件1;then       

  2.    statement1                 statement1                statement1 

  3.    statement2               else                     elif 条件2;then 

  4. fi                            statement2                 statement2 

  5.                             fi                        elif 条件3;then

  6.                                                       ...... 

  7.                                                      fi  

  8.                                                       

  #!/bin/bash
  #表示条件状态为假时执行此语句。
  if ! id $username &> /dev/null;then
      useradd $username
  fi
  
  
  #!/bin/bash
  #
  if id $1 &> /dev/null;then
    UserID= `id -u $1`  #用户存在,取用户的id号。
    echo "The User ID is $UserID"
  fi
  
  
  #! /bin/bash
  #
  if [ $1 -ge $2 ];then
    echo "the max num is $1"
  else
    echo "the max num is $2"
  fi
  
  #!/bin/bash
  # 取一串数值的最大值
  declare  -i num=0
  for i in $*; do
    if [ $num -lt $i ];then
      num=$i
    fi
  done
  
  
 #根据命令成功与否当作执行条件,则if语句后必须跟命令本身且不能引用。
  
  if grep "^[[:space:]]*$" $1 &> /dev/null; then
     echo "$1 has $(grep "^[[:space:]]*$" $1|wc -l) blank lines."
  else
     eho "no blank lines"
  fi   
   
 
 
 #!/bin/bash
 #
 if [ $(id -u $1) -eq 0 ];then
   echo "admin"
 elif[ $(id -u $1) -le 500 ];then
   echo "common user"
 else
   echo "system user"
 fi 
#if后面只是测试条件
  测试条件:命令;命令是会被执行的,把执行的结果发送的>/dev/null ;系统会自动获得命令的执行状态返回值,状态返回值为0则说明条件满足了。非0则说明条件不满足。
  测试条件:比较表达式。[ 比较内容 ],中括号两边要有空格。

    

  2)case语句


有多个测试条件时,case语句会使的语法格式更明细。

case  变量引用 in
 PATTERN1)
    分支1
    ;;
 PATTERN2)
    分支2
    ;;
....
        *)
    分支n
   ;;
esac

PATTERN:类同于文件名统配,支持使用|表示或者。
  a|b: a或者b
  *:匹配任意长度的任意字符
  ?:匹配任意单个字符
  []:指定范围内的任意单个字符。

  1. #!/bin/bash

  2. #

  3. read -p "Plz enter a char: " char             #输入一个字符

  4. case $char in

  5. [0-9])                                     #判断是否为数字

  6. echo "a digit"

  7. ;;

    [a-z])                                     #判断是否为字母

  8. echo "a char"

  9. ;;

  10. *)

  11. echo "a special word"                     #其他显示special Word

  12. ;;

  13. esac

 八:循环语句

     for循环语句

  1. for语句的格式:

  2. for VAR_NAME in LIST

  3. do

  4. 循环体

  5. done

  6. LIST:列表,中间包括一个或多个元素

  7.   1:可以是 {起始值..结束值}
      2:可以使用`seq 起始值 结束值` 或$(seq 起始值 结束值)
      3:还可以是命令(命令的执行可以得到一个列表)
  8. 退出条件:遍历结束

  9.  注意:for循环的条件是变量在列表中可以取到值,否则将不执行         循环体语句,同样for循环也可以嵌套使用

  10. for userNo in $(seq 1 5); do         #LIST为1-5个元素

  11.  useradd user${userNo}             #添加用户user-user5

  12. done




    while循环语句

  1. while语句的格式:

  2. while 测试条件; do       #测试条件为真执行一次循环,退出条件为测试条件为假。

  3. 循环体                #在循环体重不断改变着测试条件。

  4. done

  5. #!/bin/bash                              #求100以内所有整数的和

  6. declare -i count=1

  7. declare -i sum=0

  8. while [ $count -le 100 ]; do             #count的值小于等于100时执行下面的循环(为真执行)

  9.   let sum+=$count

  10. let count++

  11. done

  12. echo $sum

  13. 注意  

  14.     1:while循环是在条件满足时进入循环,当条件不满足时退出循环体        

  15.      2:循环体中须有让循环体自动的去判断条件语句的条件,否则循环将陷入死循环或者达不到我们预期的目的           

  16. 3:条件可以是个命令或者条件表达式

 


 until循环语句

  1. until语句的格式:

  2. until 测试条件; do    #测试条件为假时进入循环。

  3. 循环体

  4. done

  5. #!/bin/bash                              #求100以内所有整数的和

  6. declare -i count=1

  7. declare -i sum=0

  8. until [ $count -gt 100 ]; do             #count的值大于100时不执行执行下面的循环(为真不执行)

  9.   let sum+=$count

  10. let count++

  11. done

  12. echo $sum


  

for 循环 中循环的内容要先生成然后保存到内存当中。对于大量的循环条件,要占用很多的内存。  

对于具体数字提前未知时,不便用for来来进行循环


while 和until 必须要有退出条件


 break语句和continue语句

  1. 循环控制:

  2. continue: 提前进入下一轮循环

  3. 用于条件语句中,仅在某些个特殊场景提前进入;


  4. break [n]:跳出当前循环

  5. 用于条件语句中,


  #!/bin/bash
  #
  sum=0
  for i in {1..100};do
    if [ $[$i%3] -ne 0 ];then
       continue                                          #符合条件跳出循环。
    fi
    let sum+=$i
  done
  echo $sum
  
  
  
#!/bin/bash
#
read -p "PlZ enter a username: " userName                 #提示输入一个用户
while true; do                                            #while ture 始终为真一直循环
 if who | grep "\<$userName\>" &> /dev/null; then         #如果用户来了执行break跳出循环
   break
 fi
echo "not here."                                          #否则一直显示user not here
   sleep 5                                                # 睡5s执行一次循环
done
echo "$userName is logged on."



 函数

  1. 形式一

  2. function F_NAME {

  3.  函数体

  4. }

  5. 形式二

  6. F_NAME() {

  7. 函数体

  8. }


 #/bin/bash
 # 
dirName=/tmp/test       

function createDir {       #定义函数为createDir 

  if [ -d $dirName ];then
    echo "$dirName exits"
  else
    make $dirName
    echo "Create $dirName"
  fi
}
function main {
                        #定义函数在定义成main函数
  createDir
  createDir
}



可调用:使用函数名进行调用,函数名出现的地方,会被自动替换为函数;

函数的返回值:

函数的执行结果返回值:代码的输出
  函数中的打印语句:echo, print
  函数中调用的系统命令执行后返回的结果

执行状态返回值:函数的代码片段是否执行成功。
  函数体中最后一次执行的命令状态结果
  自定函数执行状态的返回值:return #

函数可以接受参数:
  在函数体中调用函数参数的方式同脚本中调用脚本参数的方式:位置参数
$1, $2, ...
$#, $*, $@




 信号捕捉trap

  1. trap 'COMMAND' SIGNALE ; SIGINT

     变量赋值操作

  1. ${variable:-string}

  2.   variable为空或未设定,那么返回string,否则,返回variable变量的值;

  3. ${variable:=string}

  4.   variable为空或未设定,则返回string,且将string赋值给变量variable,否则,返回variable的值;

  

     



        

 



你可能感兴趣的:(shell,脚本)