关于 shell脚本编程第一篇

                                               shell脚本编程(1)

脚本的基本格式:

              程序:指令+数据

程序编程风格分为两种:

                    过程式:以指令为中心,数据服务于指令

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

过程式编程有以下几个特点:

                        顺序执行

                        循环执行

                        选择执行

shell编程:

          过程式、解释执行

          编程语言的基本结构

          数据存储:变量、组数

          表达式:a+b

          语句: if                        

shell程序:是一个过程式的解释器,提供了编程能力,解释执行

程序的执行过程:先把源码程序翻译成机器语言(生成可执行的文件),然后解释执行。

对于过程式编程而言,把一行源码程序翻译成机器语言,然后执行,在翻译下一行的源码程序为机器语言,然后再次执行

对于计算机,只能识别的是二进制文件

编程语言:

       低级:

           汇编语言

       高级:

           编译过程:高级语言>编译器>目标代码 如:java ,C          

           解释过程:高级语言>解释器>机器代码 如: shell,perl,python

           

shell 脚本其实就是以一系列命令组合起来的文本文件,这些命令组合起来完成一个或者一项功能。

 也可以这样理解 shell脚本是包含好一些命令或声明,并符合一定格式的文本文件            

格式要求:shell程序开头的环境指定,我们称之为shebang机制

        #!/bin/bash

        #!/usr/bin/python

        #!/usr/bin/perl

        各种命令组合在一起,形成一个脚本

shell脚本的用途有:

                 自动化常用命令

                 执行系统管理和故障排除

                 创建简单的应用程序

                 处理文本或文件

     

创建shell脚本:

             使用编辑器来创建文本文件

             第一行必须包括shell声明序列:#!  #!/bin/bash

             添加注释信息 以#开头     

     

运行脚本:

        给予执行权限,通过具体的文件路径制定文件执行

        直接运行解释器,将脚本作为解释器程序的参数运行

脚本调式:

        bash -n /path/to/some_script     检查脚本中是否语法错误

        bash -x /path/to/some_script     调试执行

       

  

shell脚本格式示例

#!/bin/bash/        开头格式

#                   注释信息

# Author: root      

# date: 20160812-08:12:08

# Vervion: 0.0.1

# Description:

# Synopsis:

   echo "信息内容"

关于变量:

         什么是变量:命名的内存空间

                     数据存储方式

变量作用类型:

            作用:

                数据存储格式

                参与运算

                表示的数据范围

            类型 : 

                 字符

                 数值: 整型,浮点型

                     

      

变量类型分为两类:

强类型:定义变量是必须指定类型、参与运算必须符合类型要求;调用未声明变量会产生错误

弱类型:无需指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无须是想定义可直接调用

变量命名法则:

            不能使用程序中的保留字:例如if,for等

            只能使用数字、字母及下划线,且不能以数字开头

            要做到看到变量名称就知道是什么意思;见名知意

            统一命名法则:驼峰命名法   

            大驼峰:两个单词开头字母为大写

            小驼峰:两个单词,第一个开头为小写,第二个开头为大写

bash中变量的种类:

根据变量的生效范围等标准可分为:   

                              本地变量:生效范围为当前shell进程;对当前shell之外的其他shell进程包括当前shell的子shell进程均无效;简单来说,本地变量,只能对本地使用

                              环境变量:生肖范围为当前shell进程以及子进程。

                              局部变量:生效范围为当前shelll进程中某代码片段(通常指的是函数)

                              位置变量:$1,$2,$3,….表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数

                              特殊变量:

                                       $?  上个命令是否执行成功

                                       $0  表示命令本身

                                       $#  传递给脚本参数的个数

                                       $*  传递给脚本的所有参数

                                       $@  引用传递给脚本的所有参数

                                       pstree   查看树形结构的进程        

本地变量: 

         变量赋值: name='value' (值) 值可以引用         

                  1  可以是直接字符串 例如 name="root"

                  2  变量引用   例如 name="$username"

                  3  命令引用   例如 name=`命令`,name=$(命令) 

         变量引用:$name,${name}

                  "" 弱引用,其中的变量引用会被替换成变量值

                  '' 强引用, 其中的便碧昂引用不会被替换变量值,而且保持原字符串

                  显示已经定义的所有变量:set

                  销毁变量:unset namme

练习

1编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPV4地址操作系统版本,内核本本,CPU型号,内存大小,硬盘大小

~]# vim systeminfo.sh

#!/bin/bash

#

ip=`ifconfig | grep 'inet\>' | grep -v '127.0.0.1' | tr -s ' ' | cut -d' ' -f3`

cpu=`lscpu | grep -i "model name:"`

neicun=`free -h |sed -n '2p' |tr -s ' ' | cut -d' ' -f2`

cipan=`fdisk -l | sed -n '2p' | sed -r 's/.*[[:space:]]([0-]9.*M).*/\1/g'`

echo 'hostname:'`hostname`

echo 'hostip:'$ip

echo 'OS version:'`cat /etc/redhat-release`

echo 'neihe:'`uname -r`

echo 'cpu:'$cpu

echo 'neicun:'$neicun

echo 'cipan:'$cipan

保存退出,chmod +x systeminfo.sh 加上执行权限,可直接运行

2编写脚本/root/bin/backup.sh,可实现将/etc/目录备份到/root/etcYYYY-mm-dd中

~]# vim backup.sh

#!/bin/bash

backdir="/root/etc$(date +%F)"

cp -a /etc/. $backdir && echo "comon $backdir stop." 

保存退出,chmod +x backup.sh 加上执行权限可直接运行

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

#!/bin/bash

#

cipanname=`df |grep '/dev/sd' | tr -s ' '|sort -nr -t' ' -k5|cut -d' ' -f1`

shiyonglv=`df |grep '/dev/sd' | tr -s ' '|sort -nr -t' ' -k5|cut -d' ' -f5`

echo $cipanname

echo $shiyonglv

保存退出,chmod +x disk.sh 加上执行权限可直接运行

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

#!/bin/bash

#

echo -e "lianjie: \n\tlianjieshu\tip"

netstat -nt |tr -s ' '|cut -d' ' -f5| tr -cs '0-9.' '\n'|egrep '([0-9]+.){3}[0-9]+'|sort|uniq -c|sort -nr|tr -s ' ' '\t'

环境变量;

        变量声明、赋值

        export name=值      输出 名称 值

        declare -x name=值  声明 选项 名称 值

变量引用: $name,${name}

显示所有的环境变量:

                  export

                  env

                  printenv

                  销毁 : unset name 

 bash中有许多内建的环境变量:PATH,SHELL,USRE,UID,HISTSIZE,HOME,PWD,OLDPWD,HISTFILE,PS1

  

只读变量:只能读,但不能修改和删除

         readonly name     只读

         declare -r name   声明

位置变量:在脚本代码中调用通过命令传递给脚本的参数

             $1,$2,$3…   对应调用第1.第2第3等参数

             $0  表示命令本身

             $*  传递给脚本的所有参数,全部参数何为一个字符串

             $@  引用传递给脚本的所有参数,每个参数为独立字符串

             $#  传递给脚本参数的个数,

             $@ $* 只有在被双引号包起来时候才会有差异

         

bash中的算数运算:help let

                 +,-,*,/,% 取模式(取值)**(乘方)

                实现算数运算:

                1 let var=算数表达式

                2 var =$[算数表达式]      ]# number=$[2**3]     ~]# echo $number

                3 var =$((算数表达式))   ~]# number=$((2**3))   ~]# echo $number

                4 var =$(expr表达式 arg1 arg2 arg3…) 如A=$(expr $B \* $C)

                5 declare -i var = 数值

                6 echo  '算数表达式' | bc

                注意:*乘法符号有些场景中需要转义

                bash有内建的随机数生成器:$RANDOM(1-32767)

                echo $[$RANDOM%50]  表示0-49之间的随机数

                echo $[$RANDOM%50+2] 表示1-50之间的随机数

增强型赋值:

          +=,-=,*=,/=,%=

          使用方法:let var+=5    var值就是5

          自增,自减

          let var+=5      var=5 

          let var++       在原有的数值上面加上1 比如原先设定的是5执行一次let var++就相当于加上数值1      

          let var-=1      在原有的数值上面减去1个数值

          let var–       在原有的数值上面减去1个数值

练习

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

~]# vim sumdi.sh

#!/bin/bash

#

uid1=`sed -n '10p' /etc/passwd | cut -d: -f3`

uid2=`sed -n '20p' /etc/passwd | cut -d: -f3`

let sumid=$uid1+$uid2

echo -e "The 10 user ID is $uid1 ;\nthe 20 user ID is $uid2 ;\n\tthe sum of two users ID is $sumid ."

  

保存退出 chmod +x sumid.sh 加上执行权限

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

~]# vim sumfile.sh

#!/bin/bash

#

file1=`ls -A /etc | wc -l`

file2=`ls -A /var | wc -l`

file3=`ls -A /usr | wc -l`

let sumfile=$file1+$file2+$file3

echo "$sumfile"

逻辑运算

在shell编程当中支持一些逻辑运算:    true1 真为1 false0 假为0

                               与运算:

                                     1与1=1  1&&1=1    1和任何数相与 是原值  1和1相与为原来的值1

                                     1与0=0  1&&0=0    0和任何数相与 是0     1和0相与为原来的值0

                                     0与1=0  0&&1=0    0和1相与 等0

                                     0与0=0  0&&0=0

                               或运算:

                                     1或1=1   1||1=1    只要有一个是真结果就为真,       

                                     1或0=1   1||0=1           只要两个都是假结果就为假,

                                     0或1=1   0||1=1       

                                     0或0=0   0||0=0

                               非运算:

                                     !1=0     非真 则为假

                                     !0=1     非假 则为真

短路运算:

        短路与:

               第一个为0, 结果必定为0             命令1与命令2

               第一个为1,第二个必须要参与运算      假0    假0   如果命令1成功将执行2

                                                           如果命令1失败,将不执行命令2 

       短路或:

              第一个为1,结果必定为1              命令1命令2    如果命令1执行成功将不执行命令2

              第一个为0,第二个必须要参与运算      真1   真1    如果命令1执行不能功执行命令2

         异或:^

             异或的两个值,相同为假,不同为真        ‘异性相吸 ,同性为假’  两个值相同为假,不相同则为真

      

两种聚集命令的方法:

                  复合式:date; who| wc -l

                          命令会一个接一个地运行   顺序执行,从左往右生效

         

                 子shell:(date;who | wc -l)>> /tmp/tarce

                          可以执行单个体命令

                          (date; who)| wc -l可以先执行括号里面的命令

退出状态进程使用退出状态来报告成功或失败

                 0  表示成功 ,1-255 代表失败

                 $? 变量保存最近的命令退出状态

                    例如 echo $?  可以查看上一条命令是否成功或失败

自定义退出状态码: exit

                 注意:

                     1 脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字

                     2 如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

      

条件测试:

        判断某需求是否满足,需要有测试机制来实现;

        专用的测试表达式需要有测试命令辅助完成测试过程;

        若真,返回的是0

        若假,返回的是1  

        测试命令:

                test 表达式          $w = $r

                test [表达式]  ]   [ $w = $r ]

                test [[表达式]] ] [[ $w = $r ]]

        注意:表达式 前后必须有空白字符

条件性的执行操作符:

 根据退出状态而定,命令可以有条件地运行

命令1 && 命令2  短路与, 命令1成功,将执行命令2    ,如果命令1失败,将不执行命令2

命令1 || 命令2  短路或, 命令1成功,将不执行命令2 ,如果命令1失败,将执行命令2

bash 的测试类型

       数值测试:

              -gt  是否大于           

              -ge  是否大于等于

              -eq  是否等于

              -ne  是否不等于

              -lt  是否小于

              -le  是否小于等于

       字符串测试:

               ==  是否等于

               >   是否大于

               <   是否小于

               !=   是否不等于

               =~    左侧字符串是否能够被右侧的表达式所匹配

                  注意;此表达式一般用于[[ ]]

               -z 字符串      字符串是否为空,空为真、不空为假

               -n 字符串      字符串是否不空, 不空为真,空为假

               注意:用于字符串比较时的用到的操作数都应该使用引号

文件测试  :

        存在性测试:

                 -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     文件描述符是否已经打开并且与某终端相关

            -N file   文件上一次杜宇之后是否被修改过            

            -O file   当前有效用户是否为文件属主

            -G file   当前有效用户是否为文件属组

    双目测试::

      file1 -ef file2       文件1和文件2 是否指定向同一个设备上的相同inode 是否为同一个文件

      file1 -nt file2       文件1是否新于文件2

      file1 -ot file2       文件1是否旧与文件2              

 组合测试条件: 

       第一种方式: 

         命令1 && 命令2  并且

         命令1 || 命令2  或者

         !命令     非

         例如 [ -e file ] && [ -r file ]                

        第二种方式:

           表达式1 -a 表达式2  并且

           表达式1 -o 表达式2  或者

           !表达式   非

                  

                 

练习

编写脚本/root/bin/nologin.sh和login.sh,实现禁止和允许普通用户登录系统。

#!/bin/bash

#

[ -f /etc/nologin ] && echo "user disable login already" || (touch /etc/nologin; echo user disable login )                

   禁止普通用户登录              

#!/bin/bash 

#

[ -f /etc/nologin ] && (rm -f /etc/nologin;echo user enable login) ||  echo user disable login already              

   允许普通用户登录             

                 

计算1+2+3+…+100的值                 

#!/bin/bash

#

shuzi=`echo {1..100}|tr ' ' '+'| bc`

echo $shuzi                 

                 

                 

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

(0)
小马哥小马哥
上一篇 2016-08-15
下一篇 2016-08-15

相关推荐

  • 文本处理工具

    文本处理工具 一、文本处理命令less,cat,more,sort 1.less  less :一页一页地查看文件或STDIN 输出  查看时有用的命令包括:   /文本  搜索 文本   n/N 个 跳到下一个 or  上一个匹配   less 命令是man…

    系统运维 2016-08-08
  • NFS(Network File System)介绍与应用(双httpd + php-fpm + nfs + mysql 搭建discuz论坛)

    NFS相关介绍 一、NFS简介     1. NFS(Network File System): NFS是一个文件共享协议, 也是是在类Unix系统中在内核中实现的文件系统。      2. 起源: 最早是由SUN公司研发,非常古老,只是实现文件共享,安全控制方面比较简…

    Linux干货 2015-07-21
  • Hadoop Hive sql语法详解

    Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构 化的数据文件映射为一张数据库表,并提供完整的SQL查询功能,可以将SQL语句转换为MapReduce任务进行运行,通过自己的SQL 去查询分析需 要的内容,这套SQL 简称Hive SQL,使不熟悉mapredu…

    Linux干货 2015-04-13
  • MySQL/MariaDB数据库备份与恢复

    前言 数据库一般存放着企业最为重要的数据,它关系到企业业务能否正常运转,数据库服务器总会遇到一些不可抗拒因素,导致数据丢失或损坏,而数据库备份可以帮助我们避免由于各种原因造成的数据丢失或着数据库的其他问题。本文将讲解MySQL/MariaDB数据库的几种备份方法。 基础知识 备份类型 完全备份:备份整个数据库 部分备份:仅备份其中的一张表或多张表 增量备份:…

    系统运维 2015-05-23
  • Centos 7 DNS配置及理论详解

    DNS是什么及BIND讲解内容 域名系统(英文:Domain Name System,缩写:DNS)是internet的一项服务。它作为将域名和IP地址相互映射服务,能够使人更方便地访问互联网。DNS使用TCP和UDP端口53。当前,对于每一级域名长度的限制是63个字符,域名总长度则不能超过253个字符。讲解内容:    DNS名称解析方…

    Linux干货 2016-04-25
  • vim浅谈

            在Linux的世界里,绝大部分的配置文件都是以ASCII的纯文本形式存在的,所以作为一名优秀的Geek,熟练掌握一种文本编辑辑器是非常重要的。         Linux世界中的文本编辑器有很多…

    Linux干货 2015-04-27

评论列表(1条)

  • 马哥教育
    马哥教育 2016-08-16 16:56

    总结的很好,很细致,结构清晰,注意理论与实践相结合。