bash脚本编程基础知识

shell脚本语言编程之bash

shell简介

什么是shell:
    shell是Linux的用户界面,提供了用户与内核进行交互的接口,他接收了用户的指令,并将指令送入内核去执行
    shell即是一种高级程序语言,也是一种命令解析语言
    
shell脚本有点:
    开发简单、可移植性强(使用POSIX所定义的功能)、简单性
    
shell编程:
    用于系统管理工作,或是结合现有的程序或命令完成小型的或特定的工作。
    
编程语言分类以及工作原理
    
  编译语言:高级语言-- >编译器-- >目标代码 
    编译语言源代码运行时需要编译器转换成程序文件,编译语言举例: java, C#
  解释语言:高级语言-- >解释器-- >机器代码
    由解析器直接读入代码,将其转换成内部形式 ,解析语言举例:shell, perl, python
  
编译模型:
    过程式:以指令为中心,数据服务于代码
    面向对象式:以数据为中心指令服务于数据
   
shell编程格式:
    首行shebang机制
    #!/bin/bash
  
 shell脚本用途:
     
     自动化常用命令
     执行系统管理和故障排除
     创建简单的应用程序
     处理文本或文件

创建shell脚本

    
    第一步:创建本文文件,首行添加#!/bin/bash
                    #注释
    第二步:运行脚本

shell脚本运行

       
        一、给予执行权限,在命令行上指定脚本的绝对或相对路径
        二、直接运行解释器,将脚本作为解释器程序的参数运行

   1.png

   2.png

shell脚本第一个实例:hello word

   shell.png

bash脚本调试

    
    bash - n /path/to/some_script
    检测脚本中的语法错误
    bash - x /path/to/some_script
    调试执行

脚本变量

    
    变量:命名的内存空间
         数据存储方式:
         字符:
         数值:整型,浮点型
       
        作用:
            1、数据存储格式
            2、参与的运算
            3、表示的数据范围
            
        类型:
        字符
        数值:整型、浮点型
    变量命名法则:
        1、不能使程序中的保留字:例如if, for;
        2、只能使用数字、字母及下划线,且不能以数字开头
        3、见名知义
        4、统一命名规则:驼峰命名法
    
    shell中变量属于弱引用,无须指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用
            如: bash 不支持浮点数
            
    bash中的变量种类
        本地变量:仅对当前shell进程生效
        环境变量:对当前shell以及子shell生效
        局部变量:生效范围为当前shell进程中某代码片断(通常指函数)
        位置变量:$1, $2, ...来表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数
        特殊变量:$?, $0, $*, $@, $#

本地变量

    变量赋值: name=‘value’,
        以下是变量可引用的值:
               1、可以是直接字串:name=“root"(注意等号左右两边不能有空格哦)
               2、变量引用:name="$USER"
               3、命令引用:name=`COMMAND`, name=$(COMMAND)
               
       变量引用: ${name}, $name
           三种引号使用!!!!!
        "":弱引用,其中的变量引用会被替换为变量值
        '':强引用,其中的变量引用不会被替换为变量值,而保持原字符串
        ``:能识别命令
        
       显示已定义的所有变量: set
       删除变量: unset name


证明环境变量只能在当前shell中使用

在当前shell中定义变量name=wangNN ——>在打开一个子shell输出name变量为空
    pstree :显示进程树。可以查看当前终端shell的结构

    6.png



bash脚本编程小试牛刀:

  
  1、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名, IPv4地址,操作系统版本,内核版本,CPU型号,内存大
  硬盘大小。
[root@centos7 bin]# cat systeminfo.sh 
#!/bin/bash
echo "the hostname is:`hostname`"
echo "localhost IPV4 is:`ifconfig |sed -n "2p" |sed -e "s@.*inet@@" -e "s@netmask.*@@" `"
echo "the operation bersion is:`cat /etc/centos-release`"
echo "the kenel information is:`uname -r`"
echo "the cpu is:`lscpu |head -1|sed "s@.*[[:space:]]\+\b@@"`"
echo "the member size is:`cat /proc/meminfo |head -1 |tr -s " "|cut -d " " -f 2,3`"
echo "the hard /dev/sda size is:`fdisk -l |grep sda|head -1|sed "s@.*:@@"|sed "s/,.*//"`"
echo "the hard /dev/sdb size is:`fdisk -l |grep sdb|head -1|sed "s@.*:@@"|sed "s/,.*//"`"
[root@centos7 bin]#
2、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY- mm- dd中

    3.png

3、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值

    4.png

4、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址和连接数,并按连接数从大到小排序

    5.png

环境变量

变量声明和赋值
    export name="value"
    declare -x 变量名=值
变量引用
    $name ${name}
      
显示所有环境变量
    env
    export
    printenv
    
   
删除变量:unset 变量名

证明环境变量可以在子shell中应用

    定义环境变量——>bash 进入子shell ——>echo $name发现变量有值

    7.png

只读变量:

  只读变量:只能声明,不能删除,退出当前shell之后自动消失

  8.png

位置参数变量

 
    $?:上一条执行命令结果,0成功1代表失败
  $0:当前shell类型                
  $@:将传递的参数展开成多个参数
    $*:将传递的参数作为一个整体           
    $#:目前进程中的参数个数

   $*和$@区别

   $*和$@都指传递多个参数,单独打印时,不能看出区别,当下一个脚本调用时$@ 将传递的参数展开成多个,$*将多个参数捆绑在一起

   只有添加" "他们才会有区别,不加" "$*默认将多个参数展开成多个参数进行传递

    9.png

bash中的算数运算符

    +, - , *(使用时需要\进行转义), /, %取模(取余) , **(乘方)
    bash 中实现算数运算的几种方法:
    1、let var=算数表达式
    2、var=$[算数表达式]
    3、var=$((算数表达式))
    4、var=$(expr $num1 + $num2 ) 
    5、declare -i var=数值
        echo "算数表达式" |bc (如果是数值 1+2 可以是用'',如果引用的是变量就要使用"$num1+$num2")
   bash有内建的随机数生成器: $RANDOM( 1 - 32767)
   echo $[$RANDOM%50] : 0- 49之间随机数

 实现算数运算的方法

    1、使用let
        let:求算是表达式中的值

    bash脚本编程基础知识

  2、使用[]
      [:内置命令,判断条件表达式,与test同义,但是必须使用]结尾。

    bash脚本编程基础知识

   3、使用(())

    bash脚本编程基础知识

    4、使用expr
           expr :只能计算整数,并且表达式每个参数之间要添加空格

    15.png

赋值

     增强型赋值:
        +=, - =, *=, /=, %=
        let count+=3 自加3后自赋值
         自增,自减:
        let var+=1
        let var++
        let var- =1
        let var--

练习二

 练习 1:写一个脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID之和

    [root@centos7 bin]# cat sumid.sh 
    #!/bin/bash
    #author:wangNanNan
    #time:20160810
    #fuction:calculate the sum of the two userID
    userID1=`cat /etc/passwd |sed -n "10p" |cut -d: -f3`
    userID2=`cat /etc/passwd |sed -n "20p" |cut -d: -f3`
    SUM=$[userID1+userID2]
    echo "the sum of he tenth userID and the twenth usrID is:$SUM"
    unset userID1
    unset userID2
    unset SUM
    [root@centos7 bin]#

 练习 2:写一个脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和

   
    [root@centos7 bin]# cat sumspace.sh 
    #!/bin/bash
    #author:wangnannan
    #time:20160810
    #function:calculate the sumspace of the two file
    fistFileSpace=`grep -c '^$' $1 `
    secondFileSpace=`grep -c '^$' $2 `
    sum=$[ fistFileSpace + secondFileSpace ]
    echo "两个文件空白行之和为:$sum"
    unset fistFileSpace
    unset secondFileSpace
    unset sum
    [root@centos7 bin]#

 练习 3:写一个脚本/root/bin/sumfile.sh,统计/etc, /var,/usr目录中共有多少个一级子目录和文件
    17.png 

逻辑运算符

    非:! 与:& 或:|


    与:两个数字或条件进项进行与运算,其中有一个为假,结果为假

    或:两个数字或条件进项进行与运算,其中有一个为真,结果为真

   

   
     短路与:
    第一个为0,结果必定为0;
    第一个为1,第二个必须要参与运算;
    短路或:
    第一个为1,结果必定为1;
    第一个为0,第二个必须要参与运算;
    异或: ^
    异或的两个值,相同为假,不同为真


聚合命令

   
    复合式: date; who | wc - l
        命令会一个接一个地运行
    • 子shell: 
        (date; who | wc - l ) >>/tmp/trace所有的输出都被发送给单个STDOUT和STDERR

退出状态

   
   进程使用退出状态来报告成功或失败
        0:代表成功
        1-255:代表失败
    
    例如:
    $ ping - c1 - W1 hostdown &> /dev/null
    $ echo $?
    
    自定义bash退出状态码
        exit[n];
        shell 脚本遇到exit,会立即退出,退出状态码取决于exit[]后面的数字,如果未定义,取决于脚本最后一条命令执行的状态码

条件测试

    

 

   测试命令:
        • test EXPRESSION
        • [ EXPRESSION ]
        • [[ EXPRESSION ]]
        注意: EXPRESSION前后必须有空白字符
 
     test命令:检测文件类型或比较值是否相等
         格式:test 表达式
     test命令两种格式:
         长格式:test $A=$B
         短格式:[ "$A" == "$B" ] 
     
     数值类测试:
         -eq:是否等于
         -ge:是否大于等于
         -le:是否小于等于
         -gt:是否大于
         -lt:是否小于
         -ne:是否不等于
         
    字符串类测试:
        ==:是否等于;
        >: ascii码是否大于ascii码
        <: 是否小于
        !=: 是否不等于
        =~: 左侧字符串是否能够被右侧的PATTERN所匹配,此表达式一般用于[[ ]]中;
        - z "STRING":字符串是否为空,空为真,不空为假
        - n "STRING":字符串是否不空,不空为真,空为假
        注意:用于字符串比较时的用到的操作数都应该使用引号

练习题:

1、写一个脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;
如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数
    
    [root@centos7 bin]# cat argsum.sh 
    #!/bin/bash
    #author=wangnannan
    #time=20160810
    #function:argument count
    [[ $# -lt 1 ]] && echo "Should at least give a parameter;`exit`" || echo "the first file Blank row :`grep -c "^$" $1`"
    [root@centos7 bin]#
2、写一个脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提
示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问 ”

    [root@centos7 bin]# cat hostping.sh 
    #!/bin/bash
    #author:wangnannan
    #time20160810
    #fuction:test one host can bi communicate
    echo -e "please input the ipv4\c"
    read ipv4
    ping -c1 $ipv4 && echo "the host can be arrive" || echo "the host no arrive"
    [root@centos7 bin]#


文件测试

    存在性测试
        - a FILE:同- e
        - e FILE: 文件存在性测试,存在为真,否则为假;
        
    存在性及类别测试
        - b FILE:是否存在且为块设备文件;
        - c FILE:是否存在且为字符设备文件;
        - d FILE:是否存在且为目录文件;
        - f FILE:是否存在且为普通文件;
        - h FILE 或 - L FILE:存在且为符号链接文件;
        - p FILE:是否存在且为命名管道文件;
        - S FILE:是否存在且为套接字文件;
    
        文件权限测试:
            - r FILE:是否存在且可读
            - w FILE: 是否存在且可写
            - x FILE: 是否存在且可执行
        文件特殊权限测试:
            - g FILE:是否存在且拥有sgid权限;
            - u FILE:是否存在且拥有suid权限;
            - k FILE:是否存在且拥有sticky权限;
            
    文件大小测试:
            - s FILE: 是否存在且非空;
        
        文件是否打开:
            - t fd: fd表示文件描述符是否已经打开且与某终端相关
            - N FILE:文件自动上一次被读取之后是否被修改过
            - O FILE:当前有效用户是否为文件属主
            - G FILE:当前有效用户是否为文件属组
            
       双目测试:
            FILE1 - ef FILE2: FILE1与FILE2是否指向同一个设备上的相同inode
            FILE1 - nt FILE2: FILE1是否新于FILE2;
            FILE1 - ot FILE2: FILE1是否旧于FILE2;

    文件测试小练习:

        1、检测文件是否存在

        18.png

          2、检测两个文件是否为硬链接

        

        19.png


组合测试:

    
    第一种方式:
        COMMAND1 && COMMAND2 并且
        COMMAND1 || COMMAND2 或者
        ! COMMAND 非
        如: [ - e FILE ] && [ - r FILE ]
        
    第二种方式:
        EXPRESSION1 - a EXPRESSION2 并且
        EXPRESSION1 - o EXPRESSION2 或者
        ! EXPRESSION
        必须使用测试命令进行;
        
        [ - z “$HOSTNAME” - o $HOSTNAME "==\"localhost.localdomain" ] && hostname www.magedu.com

练习题

1、 chmod - rw /tmp/file1,编写脚本/root/bin/per.sh,判断当前用户对/tmp/fiile1文件 是否不可读且不可写
    
    [root@centos7 bin]# cat per.sh 
    #!/bin/bash
    [ ! -r /tmp/file1 -a ! -w /tmp/file1  ] && echo "`whoami` can not  read and not write " || 
    echo  "`whoami` can  read or  write "

    [root@centos7 bin]#
    注意:在普通用户下去运行,root不受权限限制
    
2、编写脚本/root/bin/nologin.sh和login.sh,实现禁止和充许普通用户登录系统。
    
    [root@centos7 bin]# cat login.sh 
    #!/bin/bash
    [ -a /etc/nologin ] && echo "common user is not login" || (touch /etc/nologin;echo "add file complete")
    [root@centos7 bin]#

使用read命令接受输入参数

    read [option]

    -p:不换行接受输入

    -t:接受输入时间,超过指定时间将推出程序


终极练习

1、指定文件做为参数,判断文件是否为.sh后缀,如果是,添加x权限
    
    [root@centos7 bin]# cat file.sh 
    #!/bin/bash
    echo -e  "please input filename:\c"
    read filename
    ! [ -e $filename ] && echo "the file not exit;" && exit
    ! [[ $filename == "/.*(\.sh)\b/" ]] && echo "please input .sh file;`exit`"
    [ -x $filename ] && echo "the file have x" || chmod +x $filename 
    [root@centos7 bin]#
2、判断输入的IP是否为合法IP
    [root@centos7 bin]# cat ipcheck.sh 
    #!/bin/bash
    #author:wangnannan
    read -p "please input IPv4:" ipv4
    echo $ipv4 |egrep -q  "^(\<([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 "ip legal" || echo "this ip is not legal"
    [root@centos7 bin]# vim ipcheck.sh
    [root@centos7 bin]#

 3、计算1~100的值

    [root@centos7 bin]# cat sum100.sh 
    #!/bin/sh
    #author:wangnannan
    #description:sum 1-100
    echo "caculate 1-100 sum:"
    for i in {1..100};do
	sum=$[$sum+$i]
	done
    echo "sum is:$sum"
    exit
    [root@centos7 bin]# 
    
    
    方法二
    [root@centos7 bin]# cat sum1002.sh 
    #!/bin/bash
    int=`seq 1 100`
    echo $int |tr " " "+" |bc
    [root@centos7 bin]# 

    
    方法三
    
    [root@centos7 bin]# seq -s + 1 100 |bc
    5050
    [root@centos7 bin]#
4、输入起始值A和最后值B,计算从A+(A+1)...+(B-1)+B的总和
    [root@centos7 bin]# cat AB.sh 
    #!/bin/bash
    read -p "plese the first num:" A
    read -p "plese the second num:" B
    [ $A -gt $B ] && echo "input error" && exit ||echo "A..B的和:` seq  -s + $A $B |bc`"
    [root@centos7 bin]#

原创文章,作者:wangnannan,如若转载,请注明出处:http://www.178linux.com/33909

(0)
wangnannanwangnannan
上一篇 2016-08-15
下一篇 2016-08-15

相关推荐

  • httpd的特性(初阶应用)

    httpd的特性   httpd常用配置/etc/httpd/conf/httpd.conf 1、修改监听的IP和PORT Listen [IP:]PORT (1)省略IP表示为0.0.0.0 (2)Listen指令可重复多次 Listen 8080 Listen 80 (3)先修改监听的socket,重启服务后方可生效 2、持久连续 KeepAl…

    2017-09-30
  • 马哥教育网络班18期+第10周课程练习

    博客作业10周.md—E:\Documents CentOS启动流程 1. 加电自检 2. 引导加载次序:BOOT Sequence 3. bootloader: 4. GRUB引导加载器 5. 进入Kernel 6. 运行init 7. 运行初始化脚本 8.启动系统服务 9. 设置登陆终端 整体总结 习题 习题1 习题2 习题3 习题4 习题5 习题6 练…

    Linux干货 2016-06-23
  • ☞LAMP

    LAMP lamp环境简介 php –> httpd Module形式安装php FastCGI方式安装php httpd-2.2配置fcgi php-xcache MySQL 安装与配置 php –> MySQL 快速部署LAMP php网站程序安装 phpMyadmin wordpress DiscuzX 脚本安装wordpress、disc…

    Linux干货 2016-10-12
  • 磁盘管理(SWAP、dd、quota、RAID、LVM)

    2016-08-26: 授课内容: 1、SWAP交换分区的创建 2、dd命令的使用 3、设定文件系统配额 4、设定和管理软RAID设备 5、配置逻辑卷、逻辑卷快照 1、swap (1)SWAP分区:模拟内存,当物理内存不足时,进程需要内存资源是,内存会把一部分没有在用的进程分页挪到硬盘的模拟内存中,腾出空间被现在需要使用内存资源的进程 即其作用是可以允许内存…

    Linux干货 2016-09-01
  • N25第四周总结(lvm)

    lvm 详解 大纲:    1、什么是lvm     2、为什么要使用lvm     3、如何实现lvm     4、lvm各项命令详解   1、什么是lvm:        lmv (Logical Volume Manager…

    Linux干货 2016-12-22
  • 第十七周作业

    1、结合图形来描叙LVS的工作原理; 工作原理 LVS分为两个组件:ipvs和ipvsadm         ipvs:工作于内核空间,主要用于使用户定义的策略生效;         ipvsadm : 工作于用户空间,主要用于用户定义和管理集群服务…

    2017-06-27

评论列表(1条)

  • 马哥教育
    马哥教育 2016-08-15 12:50

    文章内容清晰,图文并貌,内容丰满,有理论有实践,