shell编程

   编程基础

  编程基础

      编程:也就是程序+数据

          程序编程风格:

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

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

           shell程序:提供了编程能力,解释执行

程序的执行式:

       计算机只能运行二进制指令

            编程语言:

                 低级:汇编

                 高级:

                 编译:高级语言–> 编译器–> 目标代码

                          java,C#

                 解释:高级语言–> 解释器–> 机器代码

                          shell, perl, python

   编程的基本概念

          编程逻辑处理方式:

                                顺序执行、循环执行、选择执行

          shell 编程:过程式、解释执行

          编程语言的基本结构:

                      数据存储:变量、数组

                      表达式: a + b

                      语句:if

       shell脚本基础

 shell脚本基础:

         shell 脚本是包含一些命令或声明,并符合一定格式的文 本文件

         格式要求:首行shebang 机制

                      #!/bin/bash

                      #!/usr/bin/python

                      #!/usr/bin/perl

         shell 脚本的用途有:

                  *自动化常用命令

                  *执行系统管理和故障排除

                  *创建简单的应用程序

                  *处理文本或文件

  创建shell脚本

           第一步:使用文本编辑器来创建文本文件,以.sh结尾的文件

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

                                           #!/bin/bash

             添加注释:注释以#开头

           第二步:运行脚本

              给予执行权限,在命令行上指定脚本的绝对或相对路径

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

  shell脚本示例

#!/bin/bash
#author:quan
#Version: 1.0
#Description:This script displays some information about your# environment
echo "Greetings. The date and time are $(date)"
echo "Your working directory is: $(pwd)"

     执行一下,看看结果:

blob.png

  脚本调试

      bash -n /path/to/some_script   检测脚本中的语法错误

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

  变量

变量:命名的内存空间

        数据存储方式:

                        字符

        数值:整型,浮点型

       变量:变量类型

        作用:

               1 、数据存储格式

               2 、参与的运算

               3 、表示的数据范围

         类型:

               字符

               数值:整型、浮点型

               强类型:定义变量时必须指定类型、参与运算必须符合类型

          要求;调用未声明变量会产生错误

                  如 java,python

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

           如:bash 不支持浮点数

         变量命名法则:

              1、不能使程序中的保留字:例如if, for;

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

              3、见名知 义

              4、统一命名

   bash中变量的种类

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

              本地变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效

              环境变量:生效范围为当前shell进程及其子进程

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

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

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

    本地变量

         变量赋值:name=‘value’, ,

         可以使用引用value:

            (1)可以是直接字串; name=“root"

            (2) 变量引用:name="$USER"

            (3) 命令引用:name=` COMMAND `, name =$(COMMAND)

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

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

             '':强引用,其中的变量引用不会被替换为变量值,而保

         持原字符串

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

            删除变量:unset name



   课堂小练

 1 、编写脚本/root/bin/systeminfo.sh, 显示当前主机系统信息,包括主机名,IPv4 地址,操作系统版本,内核版本,CPU

首先:vi /root/bin/systeminfo.sh 编辑脚本

#!/bin/bash
echo Hostname: `hostname`;
echo IP address: `ifconfig|egrep -o "[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}"|head -n1`; 
echo System version: `cat /etc/system-release`;
echo kernel version: `uname -r`;
echo CPU type : `lscpu |grep 'Model name'|sed 's/.*://'|sed 's/^[[:space:]]\+//'`;
echo Disk size :`fdisk -l|grep "sda:"|sed 's/.*:'//|sed 's/,.*'//|sed 's/^[[:space:]]\+'//`
echo Memory size : `free -m|grep "Mem"|tr -s [[:space:]]|cut -d" " -f 2` MB

编写完毕,:wq存盘退出

执行一下程序:

blob.png

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

首先:vi /root/bin/backup.sh

#!/bin/bash
#
cp -a /etc /root/etc`date +%F`

然后,:wq存盘退出,然后执行下程序,查看/root下文件

blob.png

已经生成了今天的etc文件

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

首先:vi /root/bin/disk.sh

#!/bin/bash
echo "The max using rate is:`df |grep "/dev/sd"| cut -c 44-46 | sort -nr | head -1`%"

然后:wq存盘退出,执行程序:

blob.png

 4 、编写脚本/root/bin/links.sh, 显示正连接本主机的每个远程主机的IPv4

首先,vi /root/bin/links.sh

#!/bin/bash
echo "the links number is:"
netstat -nt |tr -s ' ' |cut -d ' ' -f5 |cut -d: -f1 |grep [0-9]|sort |uniq -c|sort -nr

:wq存盘退出,执行程序

blob.png

  环境变量

          变量声明、赋值:

                             export name=VALUE

                            declare -x name=VALUE

          变量引用:$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, … :对应第1 、第2 等参数,shift [n] 换位置

                $0: 命令本身

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

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

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

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

          示例:判断给出的文件的行数

                  linecount="$(wc -l $1| cut -d' ' -f1)"

                  echo "$1 has $linecount lines."

首先,创建脚本vi 2.sh

#!/bin/bash
linecount="$(wc -l $1| cut -d' ' -f1)"
echo "$1 has $linecount line

然后执行文件,比如查看/etc/issue行数:  

blob.png

算术运算

        bash 中的算术运算:help let

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

 实现算术运算

               (1) let var= 算术表达式

               (2) var=$[ 算术表达式]

               (3) var=$(( 算术表达式))

               (4) var=$(expr arg1 arg2 arg3 …)

               (5) declare –i var = 数值

               (6) echo ‘ 算术表达式’ | bc

          乘法符号有些场景中需要转义 ,如 如*

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

echo $[$RANDOM%50] :0-49,%表示取模

blob.png

   赋值

           增强型赋值:

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

                  let varOPERvalue

                  例如:let count+=3  自加3后自赋值

                  自增,自减:

                            let var+=1

                            let var++

                            let var-=1

                            let var–



练习

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

vi /root/bin/sumid.sh

#!/bin/bash
#
#Shows the sum of the two users
sum="`cat /etc/passwd | sed -n -e '10p' -e '20p' | cut -d: -f3`"
sum="`echo $sum | tr ' ' '+'`"
sum="$[$sum]"
echo $sum

:wq存盘退出,执行脚本:

blob.png

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

     vi /root/bin/sumspace.sh

#!/bin/bash
A=`grep "^$" $1 | wc -l`
B=`grep "^$" $2 | wc -l`
C=$[A+B]
echo "space is $C个"

:wq存盘退出,执行脚本

blob.png

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

       vi /root/bin/sumfile.sh

#!/bin/bash
etcnum=`ls -d /etc/*|wc -l`
varnum=`ls -d /var/*|wc -l`
usrnum=`ls -d /usr/*|wc -l`
echo "the totalfile is $[etcnum+varnum+usrnum]"

:wq存盘退出,执行脚本:

blob.png


逻辑运算

  true, false

         1, 0

    与:只有1与1为1,其余的都是0

         1 与 1 = 1

         1 与 0 = 0

         0  与 1 = 0

         0 与 0 = 0

    或:0或0位0,其余的都是1

         1 或 1 = 1

         1 或 0 = 1

         0 或 1 = 1

         0 或 0 = 0

    非:!比较好理解

          ! 1 = 0   非1为0

          ! 0 = 1   非0为1

 短路运算

     短路与:

         第一个为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 $?

blob.png

         成功为零,失败为1-255

    bash 自定义退出状态码

           exit [n] :自定义退出状态码;

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

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

条件测试

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

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

      评估布尔声明,以便用在条件性执行中

          • 若真,则返回0

          • 若假,则返回1

       测试命令:

          • test EXPRESSION

          • [ EXPRESSION ]

          • [[ EXPRESSION ]]

注意:EXPRESSION前后必须有空白字符

条件性的执行操作符

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

             • && 代表条件性的AND THEN

             • || 代表条件性的OR ELSE

        例如:

             $ grep -q no_such_user /etc/passwd \

             || echo 'No such user'

             No such user

blob.png

             $ ping -c1 -W2 station1 &> /dev/null \

             > && echo "station1 is up" \

             > || (echo 'station1 is unreachable'; exit 1)

             station1 is up

blob.png

bash的测试类型:

            数值测试

                       -gt: 是否大于;

                       -ge: 是否大于等于;

                       -eq: 是否等于;

                       -ne: 是否不等于;

                       -lt: 是否小于;

                       -le: 是否小于等于;

blob.png

 字符串测试

         == :是否等于;

         >: ascii 码是否大于ascii码 码

         <: 是否小于

         !=: 是否不等于

         =~: 左侧字符串是否能够被右侧的PATTERN所 所 匹配

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

        -z "STRING" :字符串是否为空,空为真,不空为假

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

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



练习

1 、写一个脚本/root/bin/argsnum.sh ,接受一个文件路径作为参数;如果参数个数小于1 ,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1 ,则显示第一个参数所指向的文件中的空白行数

vi /root/bin/argsnum

#!/bin/bash
[ $# -ge 1 ] && echo "The file's blank lines is: `grep -c '^[[:space:]]*$' $1`"
 || echo 'Atleast one argument

:wq存盘退出,执行脚本

blob.png

 2 、写一个脚本/root/bin/hostping.sh ,接受一个主机的IPv4 地址做为参数,测试是否可连通。如果能ping 通,则提示用户“该IP 地址可访问” ;如果不可ping 通,则提示用户“该IP

vi /root/bin/hostping.sh

#!/bin/bash
ping -c1 -W1 $1 &> /dev/null && echo "该ip地址可访问" || echo "该ip地址不可访问"

:wq存盘退出,执行脚本

blob.png



文件测试:

   存在性测试

          -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;

原创文章,作者:旧城以西,如若转载,请注明出处:http://www.178linux.com/34247

(0)
旧城以西旧城以西
上一篇 2016-08-15
下一篇 2016-08-15

相关推荐

  • 文本处理工具之AWK

    概述:     在之前的文章中,我们介绍过文本处理三剑客的grep、sed,本篇就简要说明下awk的用法。主要是围绕常见的一些用法进行展开,分为以下几个部分:     1、awk的基础语法     2、awk的进阶语法  &nbs…

    Linux干货 2016-09-20
  • NET25_第6周作业

    1、复制/etc/rc.d/rc.sysinit文件至/tmp目录,将/tmp/rc.sysinit文件中的以至少一个空白字符开头的行的行首加#; (1) cp /etc/rc.d/rc.sysinit /tmp cd /tmp vim rc.sysint vim命令::%s/\(^[[:space:]]\)\+/#\…

    Linux干货 2017-03-15
  • find可以这么用

    在工作中不可或缺的工具find:查找系统中的各种文件,对查找的文件进行操作,这就是find的作用。进入正题: 1、查找下系统中有一下系统中有几个文件叫issue的     [root@localhost private]#find / -name issue      …

    Linux干货 2017-03-05
  • 关于shell脚本基础第二篇

                          shell脚本编程基础第二篇 read命令 使用read来把输入的值非配给一个或者多个shell变量,可以提示用户输入一些参数等,此时我们可以使用read命令来完成此功能 re…

    系统运维 2016-08-19
  • CentOS系统启动流程

       开机不是只要单击电源钮,而关机只要关掉电源钮就可以了吗?话是这样没错啦,但是由于 Linux 是一套多人多任务的操作系统,你难保你在关机时没有人在在线,如果你关机的时候碰巧一大群人在在线工作, 那会让当时在在线工作的人马上断线的!那不是害死人了!一些数据可是无价之宝。    另外 Linux 在执行的时候,虽然你…

    Linux干货 2016-09-19
  • Linux系统发展历史

    一、什么是Linux? Linux是一种自由和开放源代码的类UNIX操作系统。该操作系统的内核由林纳斯·托瓦兹在1991年10月5日首次发布。在加上用户空间的应用程序之后,成为Linux操作系统。Linux也是自由软件和开放源代码软件发展中最著名的例子。只要遵循GNU通用公共许可证,任何个人和机构都可以自由地使用Linux的所有底层源代码,也可以自由地修改和…

    Linux干货 2016-10-14