shell 脚本编程基础

Shell脚本简介:

Shell脚本是一种特殊的程序,它是用户与linux系统内核之间的一个接口,shell是一个工具程序,在用户登录后系统启动。它解释并运行由命令行或脚本文件输入的命令,从而实现用户与内核间的交互。

Shell脚本:也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的,是利用shell的功能所写的一个程序,这个程序是使用纯文本文件,将一些shell的语法与指令写在里面,然后用正规表示法,管道命令以及数据流重导向等功能,以达到我们所想要的处理目的

 

程序:指令+ 数据

程序编程风格:

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

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

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

程序的执行方式:

 计算机:运行二进制指令;

编程语言:

低级:汇编

高级:

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

java,C#

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

shell, perl, python

编程逻辑处理方式:

顺序执行

循环执行

选择执行

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

编程语言的基本结构:

数据存储:变量、数组

表达式: a + b

语句:if

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

本文件

格式要求:首行shebang 机制

#!/bin/bash

#!/usr/bin/python

#!/usr/bin/perl

shell 脚本的用途有:

         自动化常用命令

         执行系统管理和故障排除

         创建简单的应用程序

         处理文本或文件

创建shell脚本

    第一步:使用文本编辑器来创建文本文件

第一行必须包括shell 声明序列:#!(要顶格写)

#!/bin/bash

添加注释

注释以# 开头

第二步:运行脚本

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

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

可以是用:bash 脚本名称 

        这种用法是再打开一个子shell,在子shell中运行,不对当前环境改变

       source 脚本名称

       . 脚本名称

        source 和.一样,会对当前的环境改变

脚本的调试:

    bash -n /path/to/some_script

检测脚本中的语法错误

bash -x /path/to/some_script

调试执行

 

变量:

  变量:命名的内存空间

数据存储方式:

字符:

数值:整型,浮点型

  变量类型

作用:

1 、数据存储格式

2 、参与的运算

3 、表示的数据范围

类型:

字符

数值:整型、浮点型

编程程序语言分类:

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

java,python

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

bash  不支持浮点数

变量命名法则:

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

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

3 、见名知义

4 、统一命名Shell脚本包括一些命令或声明,并符合一个格式的文件

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型号,内存大小,硬盘大小。

脚本:

                                                 system脚本.png

 

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

脚本:

backup脚本.png

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

 

disk.sh脚本.png

 

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

脚本:

links.sh脚本.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."   

算术运算

        bash 中的算术运算:help let

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

实现算术运算:

(1) let var= 算术表达式

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

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

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

(5) declare i var =  数值

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

(7) seq -s + 数值 数值 :计算两个数值之间的所有数的和

(8) scale 命令可以几位保留精度

  scale=2 表示保留两位精度(只对除法、取余、乘幂有效)

 例如:保留两位精度,echo "scale=2;111/22;" |bc  或者

              bc <<< "scale=2;111/22;"

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

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

echo $[$RANDOM%50]  0-49

赋值

      增强型赋值:

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

   let var OPER value

例如:let count+=3

自加3 后自赋值

自增,自减:

let var+=1  每次自加1

let var++  每次自加1

let var-=1  每次自减1

let var—  每次自减1

 

举例演示:

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

脚本:

sumid.sh脚本.png

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

脚本:

sumspace.sh脚本.png

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

脚本:

sumfile.sh脚本.png

逻辑运算

   true, false

1, 0

与:

1 1 = 1

1 0 = 0

0 1 = 0

0 0 = 0

:

1 1 = 1

1 0 = 1

0 1 = 1

0 0 = 0

       非:!

! 1 = 0

! 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 $?

退出状态码

           bash 自定义退出状态码

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

注意:脚本中一旦遇到exit 命令,脚本会立即终止;终止退出

状态取决于exit 命令后面的数字

注意:如果未给脚本指定退出状态码,整个脚本的退出状态码

取决于脚本中执行的最后一条命令的状态码

条件测试

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

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

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

若真,则返回0

若假,则返回1

测试命令:

test EXPRESSIO

[ EXPRESSION ]

[[ EXPRESSION ]]

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

条件性的执行操作符

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

&&  代表条件性的AND THEN

|| 代表条件性的OR ELSE

Bash的测试类型

         数值测试:

-gt:  是否大于;

-ge:  是否大于等于;

-eq:  是否等于;

-ne:  是否不等于;

 

-lt:  是否小于;

-le:  是否小于等于

         字符串测试:

== :是否等于;

>: ascii 码是否大于ascii

<:  是否小于

!=:  是否不等于

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

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

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

-n "STRING" :字符串是否不空,不空为真,空为假 (要用双中括号‘[[]]’)

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

 

举例演示:

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

脚本:

argsum.sh脚本.png

 

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

脚本:

hostping2.sh脚本.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

组合测试条件

          第一种方式:

COMMAND1 && COMMAND2  并且

COMMAND1 || COMMAND2  或者

! COMMAND

如:[ -e FILE ] && [ -r FILE ]

第二种方式:

EXPRESSION1 -a EXPRESSION2  并且

EXPRESSION1 -o EXPRESSION2  或者

! EXPRESSION

必须使用测试命令进行

举例演示:

1 chmod -rw /tmp/file1 ,编写脚本/root/bin/per.sh,判断当前用户对/tmp/fiile1文件  是否不可读且不可写

脚本:

per2.sh脚本.png

 

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

脚本:

 禁止登录:

nologin.sh脚本.png

 

允许登录:

login.sh脚本.png

 

使用read 来把输入值分配给一个或多个shell 变量:

-p 指定要显示的提示

-t TIMEOUT

read 从标准输入中读取值,给每个单词分配一个变量

所有剩余单词都被分配给最后一个变量

read -p “Enter a filename: “ FILE

流程控制

        过程式编程语言:

顺序执行

选择执行

循环执行

条件选择if语句

         选择执行:

注意 if 语句可 嵌套

单分支

if  判断条件:then

条件为真的分支代码

fi

双分支

if  判断条件; then

条件为真的分支代码

else

条件为假的分支代码

fi

           多分支

if  CONDITION1 ; then

if-true

elif CONDITION2 ; then

if-ture

elif CONDITION3 ; then

if-ture

else

all-false

fi

逐条 件进行判断,第一次遇为“真”条件时,执行其分支,而后 结束整个if 语句

条件判断:case语句

          case 变量引用 in

PAT1)

分支1

;;

PAT2)

分支2

;;

*)

默认分支

;;

esac

     case 支持glob 风格的通配符:

*:  任意长度任意字符

?:  任意单个字符

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

a|b: ab

举例演示:

1 、写一个脚本/root/bin/createuser.sh ,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id 号等信息

脚本:

createuser.sh脚本.png

2 、写一个脚本/root/bin/yesorno.sh ,提示用户输入yes no, 并判断用户输入的是yes 还是no, 或是其它信息

脚本:

yesorno.sh脚本.png

3 、写一个脚本/root/bin/filetype.sh, 判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)

脚本:

filetype.sh脚本.png

4 、写一个脚本/root/bin/checkint.sh, 判断用户输入的参数是否为正整数

脚本:

checkint.sh脚本.png

5、判断硬盘的每个分区空间和inode的利用率是否大于80,如果是,发邮件通知root磁盘

脚本:

diskinode.sh脚本.png

 

6、指定文件做为参数,判断文件是否为.sh后缀,如果是,添加x权限

sh.sh脚本.png

7、判断输入的IP是否为合法IP

脚本:

iphefa.sh脚本.png

8、计算1+2+3+…+100

脚本:

1..100.sh脚本.png

9、输入起始值A和最后值B,计算从A+A+1…+(B-1)+B的总和

脚本:

A+B=.sh脚本.png

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

(0)
ZJMZJM
上一篇 2016-08-21
下一篇 2016-08-21

相关推荐

  • 脚本实现httpd创建虚拟主机

    概述 本文使用脚本实现基于主机名的虚拟主机按需创建: 脚本可接受参数,提供独立站点目录; 生成独立站点首页; 脚本可接受参数,参数虚拟主机名称; 每虚拟使用单独的配置文件; 脚本可接受参数,参数虚拟主机名称; 环境 系统基于CentOS7.2,并通过yum安装httpd 2.4.6 建议关闭防火墙和selinux。 演示   客户机将域名解析写入/…

    Linux干货 2016-10-08
  • 命令find应用

    作业:  查找/var目录下属主为root,且属组为mail的所有文件 [root@localhost bin]# find /var/ -user root -group mail     2. 查找/var目录下不属于root、lp、gdm的所有文件    [root@localhost bin…

    Linux干货 2016-08-22
  • Linux 常用命令之cp,一个可以煮饭的工具;

    cp 复制目录和文件 对于系统管理员来说,在文件系统中将文件和目录从一个位置复制到另外一个位置是家常便饭,而cp就是可以煮饭的工具之一。cp需要源对象和目标对象,源对象在前,目标对象在后面。 1. 常用选项 基本用法 [root@local tmp]# ll total 0 -rw-rw-r–. 1 gen…

    Linux干货 2016-08-02
  • 最简单也最难:运维监控的最后1公里

    谈运维我们不得不提监控,监控是运维的起点,也是难点。随着IT架构逐渐复杂化,从前端到IT底层,中间涉及浏览器、网络、服务器、操作系统、中间件、应用、数据库等,每个环节厂商不尽相同。当出现异常需要定位哪个环节出了问题的时候,排查就耗时耗力,若使用优云监控产品,以上难题不再是问题。优云全栈运维监控覆盖了所有环节的监控,真正做到监控无盲区,运维无隐患。 运维最后一…

    系统运维 2017-01-09
  • RHCE系列之磁盘加密—-LUKS加密

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://nolinux.blog.51cto.com/4824967/1436460        LUKS (Linux Unified Key Setup)为 Linux 硬盘…

    Linux干货 2016-08-15
  • ☞keepalived

    keepalived 高可用集群 VRRP协议 keepalived 安装keepalived 主要文件 配置文件说明 【一】测试keepalived基本功能 单主模型示例 双主模型示例 通知脚本示例 【二】单主模型高可用DR类型LVS集群 配置keepalived主机 Real Server配置 测试结果 【三】双主模型高可用DR类型LVS集群 配置kee…

    Linux干货 2016-11-01