码迷,mamicode.com
首页 > 系统相关 > 详细

关于shell脚本编程第一篇

时间:2016-08-15 14:55:07      阅读:289      评论:0      收藏:0      [点我收藏+]

标签:编程语言   解释器   表达式   程序   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                

本文出自 “小马哥Linux系统运维” 博客,转载请与作者联系!

关于shell脚本编程第一篇

标签:编程语言   解释器   表达式   程序   shell   变量   

原文地址:http://xiaomag.blog.51cto.com/11842517/1837902

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!