shell脚本基础

本章学习内容

        ----------什么是shell

        ----------shell类型

        ----------shell分类

        ----------shell脚本的特点

        ----------shell脚本的语法格式

        ----------shell脚本的语法基础





一、什么是shell

     shell既是一个可执行程序,又是一种程序设计语言。作为执行程序,它交互式地解释和执行用户输入的命令,是用户和Unix/Linux沟通的桥梁;作为程序设计语言,它可以定义变量和参数,在一定程度具备编程的能力。虽然不属于系统内核的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序。




二、shell类型

    bsh,csh,zsh..众多的shell类型功用和bash大同小异,只不过语法格式有时略有不同。




三、shell脚本在编程程序语言中的分类

     <1>面向过程和面向对象分类       

        bash是面向过程式编程语言

        过程式:以指令为中心来组织代码,数据服务于代码

        对象式:以数据为中心,指令服务与数据        

     <2>编译型语言和解释性语言分类

        bash是解释型语言

        解释执行,并不像java、c那样生成.class文件再进行编译

     <3>弱类型和强类型语言分类

        bash是弱类型语言 

     ◆bash是弱类型语言相对于强类型语言带来三个改变

        <1>变量无需声明
        <2>声明和赋值可同时进行
        <3>变量需要使用$引用
     从下面几个方面对比弱类型语言和强类型语言的优缺点
         对于字符串赋值而言,因为bash中变量无需声明,所以直接赋值即可,c则需要声明。bash胜
         对于数值计算而言,都需要赋值,只不过bash可以赋值声明和赋值可同时进行。bash略胜
     示例

  int a  intb int c   c=a+b  print c    # C语言格式
       declare -i c
       declare -i a
       declare -i b
       c=a+b  echo $c  或者  c=$[a+b]  或者  c=$[$a+$b]    # bash格式

   

写为c=$[$a+$b]  是为了不与其他字符串变量引用混淆。变量引用这是弱类型语言的弱点,而且bash这个弱类型编程语言的计算能力很差。


bash中默认类型是字符

root@centos7 /tmp]#a=1
[root@centos7 /tmp]#b=2
[root@centos7 /tmp]#c=$a+$b
[root@centos7 /tmp]#echo $c
1+2
[root@centos7 /tmp]#declare -i a=1
[root@centos7 /tmp]#declare -i b=2
[root@centos7 /tmp]#c=$a+$b
[root@centos7 /tmp]#echo $c
1+2
[root@centos7 /tmp]#declare -i c
[root@centos7 /tmp]#c=$a+$b
[root@centos7 /tmp]#echo $c
3    # c不转换数值型,无法识别1+2

 


 

四、shell脚本的特点及应用   

      <1>特点:虽然shell编程不像Java那样强大,但是它们能够轻易的处理文件目录之类的对象,例如:打印一个字符串只需要一个echo即可,而不需要像java那样需要定义类和对象之类的框架结构。这也正弥补了解释型语言在速度上的缺陷。

      <2>shell脚本的用途有:

         自动化常用命令

         执行系统管理和故障排除

         创建简单的应用程序

         处理文本或文件




五、shell脚本的执行条件语法格式  

     1、执行条件:

        <1>作为可执行程序运行(给予执行权限,在命令行上指定脚本的执行路径)

           注:任何一个可执行程序,如果要执行,必须在PATH环境变量中,以保证根可以找到程序,否则无法执行

        <2>作为指定特定解释器的参数运行

     2、语法格式

         第一行必须声明默解释环境(Shabang机制):#!/bin/bash,那么它执行时会默认用当前Shell去解释这个脚本(即:$SHELL环境变量)           

     语法格式1  if语句  

     if ..; then

       ...

     [elif

       ...]

     [elif

       ...]

     [else    (保底条件)

      ...]

     fi

     语法格式2 case语句  适合离散输入的判断

     case 变量引用 in

     PATH1)

        分支1

        ;;

     PATH)

        分支2

        ;;

     *)       (保底条件)

        默认分支

        ;;

    esac

case支持glob风格的通配符:

*: 任意长度任意字符

?: 任意单个字符

[]:指定范围内的任意单个字符

a|b: a或b

    语法格式3  for语句

    for 变量名 in 变量列表; do   也可用于循环,数组

      循环体

    done

    注意:while语句完全替代for语句。当然,也仅限于像数字这样的递增数列时,如果是列出某文件列表的话,还是使用for语句。for的c语言格式也可以用于循环。

    语法格式4  while语句

    while 判断条件; do

      循环体

    done

    语法格式5  until语句

    until 判断条件; do

      循环体

    done

      注意:while和until要提前定义变量,for中在列表中以定义

    语法格式6  区分continue、break和exit

    <1>continue:退出本次循环

    <2>break:退出本轮循环

    <3>exit:退出shell

#!/bin/bash
#
for i in {1..3}; do
  for j in {1..10}; do
    [ $j -eq 7 ] && continue    # 当j=7时,退出本次循环,所以输出三次1-10,但是没有7
    echo $j
  done
#!/bin/bash
#
for i in {1..3}; do
  for j in {1..10}; do
    [ $j -eq 7 ] && break    # 当j=7时,退出第二个for循环,所以输出三次1-6
    echo $j                      此处的break可以换做cotinue 2
  done

done
#!/bin/bash
#
for i in {1..3}; do
  for j in {1..10}; do
    [ $j -eq 7 ] && exit    # 当j=7时,退出bash脚本,所以只是输出了1-6六个数字
    echo $j                       此处的exit也可以换做break 2
  done

done



语法格式7:shift

    shift会跳过指定数量的位置变量

#!/bin/bash
#
echo "1st arg is $1"
echo "all arg is $@"
shift
echo "1st arg is $1"
echo "all arg is $@"
shift
echo "1st arg is $1"
echo "all arg is $@"
shift 2    # 跳过2个位置变量
echo "1st arg is $1"
echo "all arg is $@"
[root@centos7/tmp]#bash shift.sh 1 2 3 4 5 6
1st arg is 1
all arg is 1 2 3 4 5 6
1st arg is 2
all arg is 2 3 4 5 6
1st arg is 3
all arg is 3 4 5 6
1st arg is 5    # 跳过3和4,直接输出5
all arg is 5 6




bash中传递参数的俩种方式

脚本参数 (位置参数)

read

语法格式8:read读入的变量不可以当作位置变量使用

[root@localhost ~]#vim testread.sh
#!/bin/bash
read -p "please input:" VAR
if [[ $1 == 1 ]]; then
  echo ok
fi
[root@localhost ~]#bash -x testread.sh 
+ read -p 'please input:' VAR
please input:1
+ [[ '' == 1 ]]     ######$1显示为空,证明



脚本的退出状态码

    默认取决于脚本中执行的最后一个语句

    exit定义 

函数的退出状态码

    默认取决于函数中执行的最后一条语句

    return定义    




六、shell脚本中的语法基础

    变量

    这里当然不是说字符串、整型什么的,其实 bash 中的变量都可以理解为字符串。bash 中有四种类型的变量,它们是环境变量、本地变量、位置变量和特殊变量。    

      本地变量

      环境变量  PATH  PWD   HOSTNAME  HISTORY   

         定义方法:export VALUE

                   declare -x  VALUE

      局部变量

      位置变量  $1,$2

      特殊变量  $#  $*  $@   $?  $0

   运算

     算术运算

         let a=b+c

             let a+=1

             echo $a

         a=$[$a+$b]

             echo $a

         a=`expr 2 + 3`

             echo $a

     逻辑运算

         &&  ||  !取反

         注意:如果多条命令出现在逻辑关系中,建议加小括号

   条件测试

       字符串测试  

           =~  :一般使用[[ ]]匹配模式,globbing或者正则表达式或者扩展的正则表达式

#!/bin/bash

#

read -p "input a num: " n

[ -z $n ] && echo "at least one parameter"

[[ $n =~ ^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$ ]]  && (echo "ok ip"; ping $n &> /dev/null && echo "ok access" || echo "no access"|| echo "no ok ip"


           ==

           >

           <

           !=  :以上比较的都是字符串对应的ASCII码的大小

           -z : 字符串是否为空,空为真

           -n : 

       数值测试

           -eq

           -ne

           -gt

           -ge

           -lt

           -le

       文件测试

            -e:文件是否存在

            -f:是否存在且为普通文件

            -s:文件是否不为空

            注意,测试要加[ ]

   组合测试

        -a  -o  -!

        [ ! -r /tmp/file1 -a ! -w /tmp/file1 ]

        注意:对于字符串测试和数值测试同样适用于此种格式

          1、如果要使用globbing或者正则表达式或者扩展的正则表达式要使用[[ ]],一般使用在字符串的~=中。

          2、找不到错误时可以更换[]或者[[]]


注意 :组合测试中的-a ,-o,!一般用在测试条件间的逻辑,而逻辑运算中的&&,|| 一般用在命令执行结果中的判断

注意:命令间的或是短路或的意思,条件间的或是普通或的意思

    命令引用

       $()   ``

    变量替换

       $VALUE

[root@centos7 ~]#a=1
[root@centos7 ~]#b=2
[root@centos7 ~]#ab=3
[root@centos7 ~]#echo $ab
3
[root@centos7 ~]#echo ${a}b
1b
[root@centos7 ~]#

 



七、数组

    数组也适用于文件

[root@centos7~/bin]#file=`ls /root`
[root@centos7~/bin]#echo ${file[*]}

   


    1、 数组:变量的集合,可通过数字来索引到特定的变量

    2、定义数组

       <1>声明数组

          declare -a array:声明普通数组

          declare -A array:声明关联数组,必须声明

[root@centos7~]#unset aa    #删除数组  #unset aa[#]:删除数组中某个元素
[root@centos7~]#declare -A aa
[root@centos7~]#aa=([a]=1 [b]=2 [c]=3)
[root@centos7~]#echo ${aa[a]}
1

       <2>定义数组

          aa[0]=1:定义单个数组元素

          aa=(1 2 3):定义多个数组元素

          aa=([0]=0 [2]=2]):不规则定义数组元素

    3、引用数组

       引用数组的元素  

          ${aa}:引用变量aa的值   

          ${aa}:列出第一个元素

          ${aa[0]}: 列出第一个元素

          ${#aa[0]}: 引用第一个元素的长度

          ${aa[*]}:  列出所有元素

          ${aa[@]}: 列出所有元素

          ${#aa[@]}:列出所有元素的个数




八、字符串处理

    <1>切片

       格式:${var:offset:number}

       offset:跳过的字符个数

       number:取得的的字符长度

[root@centos7~]#bb=xix:x:4369:4369::/home/xix:/bin/bash
[root@centos7~]#echo ${bb}
xix:x:4369:4369::/home/xix:/bin/bash
[root@centos7~]#echo ${bb:3:5}
:x:43
[root@centos7~]#echo ${bb: -3}    # 中间必须又空格,取后三个字符
ash
[root@centos7~]#echo ${bb:5:-3}   # 去掉前5个字符和后3个字符
:4369:4369::/home/xix:/bin/b

    <2>基于模式取子串

        #:自左向右

        @:自右向左

[root@centos7~]#cc=/var/log/messages
[root@centos7~]#echo ${cc#*/}    # 自左向右删除第一个/之前的内容,包括斜线
var/log/messages
[root@centos7~]#echo ${cc##*/}    # 自左向右删除所有/之前的内容,包括斜线
messages
[root@centos7~]#dd=http://www.magedu.com:80
[root@centos7~]#echo ${dd%:*}    # 自右向左删除第一个:之后的内容,包括:
http://www.magedu.com
[root@centos7~]#echo ${dd%%:*}    # 自右向左删除所有:之后的内容,包括:
http

    <3>查找替换

       /:第一次匹配到的

       //:所有被匹配到的

       #:行首被匹配到的

       %:行尾被匹配到的

[root@centos7~]#ee=bash:x:0:0::/root:/bin/bash
[root@centos7~]#echo ${ee/root/zhao}    # 只需要俩个/
zhao:x:0:0::/root:/bin/bash
[root@centos7~]#echo ${ee//root/zhao}
zhao:x:0:0::/zhao:/bin/bash
[root@centos7~]#echo ${ee/#bash/zhao}
zhao:x:0:0::/root:/bin/bash    # 该变行首
[root@centos7~]#echo ${ee/%bash/zhao}
bash:x:0:0::/root:/bin/zhao    # 改变行尾
[root@centos7~]#

     <4>查找并删除   

        /:  第一个

        //:行首

        /#:行首

        /%:行尾

[root@centos7~]#ff=root:x:0:0::/root:/bin/bash
[root@centos7~]#echo ${ff/r..t}
root:x:0:0::/root:/bin/bash    # 不支持正则表达式
[root@centos7~]#echo ${ff/r??t}    # 支持通配符
:x:0:0::/root:/bin/bash
[root@centos7~]#echo ${ff/r*t}
:/bin/bash
[root@centos7~]#echo ${ff//r??t}
:x:0:0::/:/bin/bash
[root@centos7~]#echo ${ff/#root}
:x:0:0::/root:/bin/bash    # 取子串也可以做到

    <5>字符大小写转换

       ^^: 所有小写转换大写

       ..:所有大写转换小写

[root@centos7~]#gg=ggggggg
[root@centos7~]#echo ${gg^^}    # 转换大写
GGGGGGG
[root@centos7~]#hh=`echo ${gg/#root}`     
[root@centos7~]#echo ${hh,,}    # 转换小写
ggggggg




九、变量赋值

    1、${var:-value}:如果var为空或未设置,那么返回value;否则,则返回var的值  

[root@centos7~]#var=prompt
[root@centos7~]#echo ${var:-tidle}
prompt

    2、${var:+value}:如果var不空,则返回value

[root@centos7~]#var=prompt
[root@centos7~]#echo ${var:+tidle}
tidle

    3、${var:=value}:如果var为空或未设置,那么返回value,并将value赋值给var;否则,则返回var的值   

[root@centos7~]#unset var
[root@centos7~]#echo ${var:=tidle}
tidle
[root@centos7~]#echo $var
tidle

    4、${var:?error_info}:如果var为空或未设置,那么返回error_info;否则,则返回var的值

[root@centos7~]#unset var
[root@centos7~]#echo ${var:?error}
-bash: var: error

  如果脚本中变量较多时,要为脚本中的变量设置配置文件,source该文件即可




十、间接变量引用

    描述:变量中存在的是另一个变量,而真正的值存在于另一个变量中

    1、引用方法

       <1>${!var}

       <2>\$$var  

[root@centos7~]#shortname=hh
[root@centos7~]#longname=haha
[root@centos7~]#name=shortname
[root@centos7~]#echo ${!name}
hh
[root@centos7~]#eval right=\$$name    # 必须借助right这个变量
[root@centos7~]#echo $right
hh

 



十一、调用shell脚本模版

    <1>编辑/root/.vimrc

[root@centos7~]#vim .vimrc 
autocmd BufNewFile *.sh 0r ~/.vim/example.sh    # 添加次行

    <>编辑/root/.vim/example.sh

[root@centos7~]#vim .vim/example.sh 
#!/bin/bash    # 添加这四行,创建脚本时会自动读入
#Author:Zhao
#Name:
#Function:

     

     



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值