shell 脚本概述
shell 是一种具备特殊功能的程序,他提供给用户与内核进行交互的的一种接口。并且把它送入到内核去执行。内核是Linux系统的核心。从开机自检就驻留在计算机的内部。shell 是一种应用程序,当用户登录Linux系统时候,shell 就会被调入内存执行。它是连接内核和应用程序的桥梁。并且由输入设备读取命令,再将其转化为计算机可以理解的机械码,Linux内核才能执行该命令。
打开shell 的方式
熟悉linux系统的用户基于shell 登录,不使用图形用户来操作Linux系统。熟悉打开shell 的方式。基于putty工具实现Linux登录。putty是一款非常小巧的工具,而且是绿色的软件。无需进行安装。输入登录主机IP地址,再单击open 按钮连接。输入用户名和登录密码就可以了。
使用putty软件连接的步骤
下载putty 运行
进入管理对应的虚拟机
shell 编程脚本的优势
脚本语言是针对编译型语言而设立的,他为了缩短编译型语言,编写-编译-链接-运行的过程而创建的计算机编程语言。由于脚本语言常常运行于底层,所处理的是字节,整数,浮点型或者其他机器层的对象。因而脚本语言是低级的程序设计语言。例如C/C++ java 都是高级程序语言。这类语言所编写的程序需要经过编译,将源码转化为目标才能运行,而脚本语言往往是解析运行的语言而非编译的语言。脚本语言的好处是简单,易用。通过解释器读入脚本程序代码。将其转化为内容执行的形式。
脚本语言:语法和结构简单
学习和使用方便
通常以容易修改程序的解释作为运行方式。不需要编译
程序开能够产生优于运行的效能。shell 脚本语言是linux /unix 系统上一门重要的语言。在Linux领域极为广泛。用shell 脚本语言可以简单是实现复杂的工作。shell 脚本语言涉及所有的linux命令的灵活使用。另外shell脚本语言还提供类似高级程序语言的的语法结构。变量和函数,循环结构,数组,算术,逻辑运算等
shell 学习
使用shell 脚本可以省去每次需要输入命令的麻烦。shell 脚本将系列的命令存放到一个文件中,我们可以通过访问这个文件去执行命令。每次都会执行一个。.bash_profile文件配置环境。再查看哪些用户在登录。我们输入这些命令完成这些操作。
..bash_profile
date
who
ifconfig
我i们可以进一步优化,我们能否将这些命令写入到一个文件之中,然后执行这个文件来执行这些操作呢?这是原始的shell 脚本
将上述的三个命令写入到下面的文件之中
cd 切换到根目录下
..bash_profile 配置命令运行环境
date
who
提高看工作的效率。
Shell 学习可以来管理集群,提高开发的效率
需要看懂运维人员编写的shell程序,shell 是一个命令行的解释器。它接受应用程序和用户命令。
接下来我们需要学习就两个:
编写脚本语言和运行脚本语言
shell的作用
解释执行用户输入的命令或者程序
用户输入一条命令,shell 就解析一条
键盘输入命令,linux 给与响应的方式,成为交互式
shell 就是一块包裹在核心的外壳处于操作系统的最外层,与用户直接对话,将用户的输入,解释给操作系统,然后处理操作系统的输出结果,输出到屏幕给与用户看的结果。
shell 脚本注释,使用#符号来作为shell 解释
注意保持良好的脚本注释,良好的编程习惯。以便于以后回顾代码。
执行脚本的运行方式
bash script.sh / sh script.sh 文件本身没有执行,没有x权限,则使用的方法,或脚本未指定shebang,重点推荐的方式。
shell 语言定义的变量,在定义数据类型的时候,不主动声明改类型。
bash的基础特性
bash是一个命令处理器,运行在文本窗口中。并且可以执行用户输入命令
bash 可以支持从文件中读取linux,称之为脚本
bash 支持通配符,管道。有助于运维人员提升工作效率
shell 变量名
设置变量
设置一个hello变量
通过echo $name 将变量名打印出来。定义的是临时的变量,会进行释放储存。
变量的替换/引用
name="hello"
echo $name
echo ${name}
变量名的规则:定义变量要见名知意
只能包含数字,字母,下划线
不能以数字开头
变量名严格区分大小写
变量名的作用域:仅针对当前的shell进程。在不同的作用域下拿到不同的值。
父子shell
1每次调用一个bash /sh解释器都会开启一个子shell ,因此不保留当前的shell 变量,通过pstree 命令查看进程树。
2调用source 是当前的shell 环境加载脚本有,因此保留变量。
`linux`,在linux反引号中的变量执行结果会被保留下来
环境变量设置
通过set寻找父子shell的变量加载
环境变量一般是用export内置的导出的命令,用于定义shell的运行环境。保证shell命令正确执行。
环境变量可以在命令行中临时创建,但是用户退出shell终端,变量会丢失。如果需要永久保存,就需要设设置环境变量的配置文件
环境变量的配置文件
用户个人配置文件 ~/ .bash_profile
~/ .bashrc
远程用户独有的文件
全局配置文件 /etc/profile
, /etc/bashrc
系统建议在创建在 /etc/profile.d
并非直接修改主文件,修改全局配置文件,影响所有的登录系统的用户。
检查系统环境变量的配置命令:
set 输出所有变量,包括局部和全局变量
env 只显示全局变量
declare 显示所有的变量 如同set
export 显示和设置环境变量的值
撤销环境变量:
unset 变量名,删除变量和函数
设置只读的变量
readonly 只有shell结束 ,只读变量失效
set 命令可以查看当前的的所有的环境变量
env 只显示全局变量
使用set |wc -l
显示所有变量的个数
env |wc -l
显示所有全局变量
delare | wc -l 这个命令和set 命令一致
只看设置的环境变量
执行export 可以查看环境变量
export 查看环境变量
unset
变量名删除创建的变量
系统保留了很多环境变量关键字
bash 内部嵌套了很多环境变量,用于定义bash的工作环境
bash 支持多命令执行
cd /desktop ; ls -l ; ls -a
中间用封号隔开就可以
环境变量初始化和加载顺序
ssh 登录linux后 系统、启动一个bash shell bash读取若干个系统环境文件,检查环境变量
/etc /profille 全局环境变量文件,为系统的每一个用户设置环境信息,当用户第一次登录时候,该文件就会被执行,并从/etc/profile中配置文件中搜索shell的设置
然会读取/etc /profile下的叫脚本。有系统许多脚本,也放入自定义登录加载的脚本,便于用户登录后立即运行脚本
运行$HOME/.bash_profile (用户环境变量配置文件)
运行$HOME/.bashrc
运行etc/bashrc
shell 特殊的参数变量
定义shell 变量 变量名不需要加美元符号
name ="变量名称"
变量的定义
字母·数字 下划线 严格区分大小写 不得数字开头
取出变量值
echo $变量名
特殊变量
shell 的特殊变量,如用在脚本,函数传递参数使用, 位置参数变量
获取shell 脚本文件名 以及脚本名称
获取shell 脚本第n个参数,其中n在1~9之间
获取shell脚本后面的参数总数个数
$@ 和 $* 的区别
``
```bash
都会返回传递给函数的所有参数
当 $* 和$@ 不被双引号包裹的时候,他们之间没有任何的区别,都是接受到每个参数看做一份数据,彼此之间用空格来分割
但是当他们被双引号包含的时候就有了很大的区别
"$*"会将所有的参数从整体上看作一份数据,而不是把每个参数看作一份数据
"$@" 仍然将每一个参数都看作一份数据,彼此之间是独立的
看出区别需要使用shell 循环的知识看出两则之间的不同。
shell特殊状态变量
$? : 上一次命令执行状态返回值,0表示正确,非0表示失败
$$ :当前shell脚本的进程号
$! : 上一次后台进程的PID
$_ : 再次之前执行的命令,最后的一个参数
查找方式:man bash
搜索 Special Paramaters
脚本控制的返回值
脚本执行结束了,会返回一个数字id,返回值
#怎么让程序后台执行
使用nohup
命令
获取上一次后台的PID
ps -ef|grep ping 查看进程命令
获取当前脚本的PID $$
获取上次命令的最后一个参数
echo $_
用这个命令进行获取上次命令的最后一个参数的
几个简单的shell 内置变量
Shell 子串
bash 一些基础的shell 内置的命令
echo eval exec export read shift
echo 命令
echo 命令
echo -n 不换行输出
-e 解析字符串的特殊字符
\n 换行
\r 回车
\b 退格
echo -n 不换行
printf 命令#打印命令
eval 命令 #执行多个命令
exec命令#不创建子进程,执行完毕,自动退出exit
exec date #显示当前时间,自动退出exit
shell 子串
学习基础语法之后,需要去应用
${变量} 返回变量值
${#变量} 返回变量的长度
${变量:start} 返回start数值之后的字符
${变量:start:length}:提取start之后的length 限制的字符
${变量#word}从变量开头删除最短匹配的word子串
${变量##word}从变量开头删除最长匹配的word
${变量%word}从变量结尾删除最短的word
${变量%%word}从变量结尾开始删除最长的匹配的word
${变量/pattern/string}用string代替第一个匹配的pattern
${变量/pattern/string}用string代替所有的pattern
返回变量的长度:${#变量}
name = "university"
上面的这个元素是有索引的
${变量}
${#变量}
${name:4} 输出ersity
${name:4:1} 输出一个字母e
${name#sity} 输出的后面删除sity
字串的实际用法
shell 变量截取字符串的方式
name ="hello大约在冬季"
从左边开始计数:
echo ${name:2}
echo ${#name}
echo ${name:2:1}
echo ${name#hello}
echo ${name##hello}
统计命令执行时长
for循环语法 shell 编程知识
语法:
for 变量 in 循环的区间
do
做什么
done
for 语句
seq:生成序列的命令
for 循环里面使用echo命令
统计命令执行的时间案例:
${#变量}返回字符串长度所用的时间
统计shell 变量长度的方法
第一种:wc | -L
第二种:echo ${#变量}
echo ${#name]
第三种:利用数值计算expr
expr 命令
expr length "${变量}"
第四种:awk 命令统计长度
echo "${name}" | awk '{print length($0)}'
字符串截取
a*c 匹配以a开头.中间任意字符,结尾以c的字符串
区分大小写
实际练习
关于变量截取的命令用法
批量修改文件名
准备测试数据源
去掉所有文件的_finished后缀
1. 思路:单个文件之间使用mv命令
2 使用shell 子串替换功能修改文件后缀名
${变量/pattern/string}用string代替第一个匹配的pattern
${变量/pattern/string}用string代替所有的pattern
利用变量的子串功能除去一些字符信息
利用变量的反引号的功能
f= baoge_1_finished.png
mv $f `echo ${f//_finished/}`
实现批量修改文件名
实现修改剩下的文件
第一步:查看未修改的文件名
ls *jpg
第二步:仅查看含有_finished 的文件
ls *fin*jpg
第三步:打印出含有_finished的文件
echo `ls *fin*jpg`
使用for循环去掉剩下的含有_finished文件
for filenanme in `ls *fin*ipg`;do mv $filename `echo ${filename//_finished/}`
shell 扩展变量
shell 扩展变量
变量的语法扩展介绍
对变量的值进行判断,处理
变量:
如果parameter为空,返回word字符串
${parameter:-word}
如果parameter为空,返回word字符串,且返回其值
${parameter:=word}
如果param为空,word当作stderr输出,否则输出变量值,用于设置变量为空导致错误时候,返回的错误的信息
${parameter:?word}
如果parameter为空,什么都不执行,否则word返回
${parameter:+word}
实际案例:
变量的阔扩展案例:
对${:-}
的案例解析
如果变量为空,就会获取后面的数值
如果变量有值不为空,就会将变量的值取出来
对${:=
}的解析
如果变量值为空,将后面的数值作为两个输出,一个是变量的输出,一个是结果的输出
变量值存在的情况,输出原始变量的值
对于${:?
}的解析
作为一个变量的判断的命令
对于${:+}
的解析
如果变量有值存在
实际应用
数据备份,删除过期数据的脚本
find xargs 搜索且删除
删除7天以上的过期数据
find 需要搜索的目录 -name 你要搜索的文件名字 -type 文件类型 -mtime +7|xargs rm -rf
find ${path}
为什么需要父子shell
source 执行脚本,只在当前shell环境中执行生效
指定bash sh解释器运行脚本 ,是开启子shell 运行脚本命令
./script 都会指定shebang 通过解释器运行。也是开启子shell运行命令
父shell 的概念
通过pstree /或ps -ef --forest
查看进程关系
pstree
ps -ef --forest
两个命令查看进程的命令,查看父子shell
需要理解进程父子shell的概念。在shell编程中会用到父子shell的概念。
多个子shell命令:在父shell里里面可以有多个子shell。可以通过进程查看这个概念
创建进程列表
ls;cd;pwd;echo "ok" 这个只是依次运行每个命令,但是不是列表
列表:
是有容器包裹起来的数据
shell 进程列表理念,需要使用小括号。如下执行的方式,称之为进程列表
(cd ~;pwd;ls;cd/tmp/;ls;pwd)
检测是否在子shell环境中
BASH_SUBSHELL
该变量的特点,如果是0就是父shell环境,否则就是子shell
echo $BASH_SUBSHELL
学习子shell的意义:开启子shell运行这个命令,不耽误做其他的事情
进程列表会开启子shell去运行
(cd ~;pwd;ls;cd/tmp/;ls;pwd)
子shell嵌套运行
(pwd ;(pwd;$BASH_SUBSHELL))
子shell嵌套运行,在脚本开发中。经常使用子shell进行多进程的处理提高程序并发执行效率。
shell 内置命令,外置命令
shell
linux 指令
shell内置命令和外置命令的区别
内置命令:在系统启动就加载入内存。常驻内存,执行效率更高,但是占用资源
外置命令:用户需要从硬盘中读取程序文件,再读入内存加载。
外置命令:称之为自己单独下载的文件系统命令,处于bash shell 之外的程序。
我们可以通过linux下的type命令:验证是否为内置命令,外置命令思维
shell 脚本开发
shell脚本开发
使用shell脚本完成自动化的操作。
shell执行多条命令,我们可以通过shell编程,通过逻辑代码实现一个脚本文件。再去执行这个脚本文件。如何实现脚本文件
Shebang
#!/bin/bash
#!/bin/perl
#!/bin/python
执行脚本的方式
source my_firsh.ssh 利用source
. my_first.ssh 利用.
bash my_first.sh
实现一个简单的案例,执行脚本的方式
vim test_date.sh
在vim编辑器中写入echo "当前的时间日期为:`date`"
在执行这个脚本文件
bash test_date.sh
echo 和转义字符的概念
所谓转义符
所谓转义字符,还原符号,原本的意思,不会被阅读为特殊的含义。双引号使用
"\$"才会输出$ 符号。
使用单引号就很方便,直接输出的特殊的符号
变量在脚本中的使用
变量被引用的时候,会赋予其值,脚本中的变量,在shell执行完毕后就会消失。是否消失根据执行的方式决定。变量在echo中的使用。
当你用不同的方式执行脚本产生的结果不一样
source 和. 在当前的bash环境执行。
shell数值运算
使用shell做数学运算
需要了解:
数学计算:Linux 的用于数学运算的符号和命令
shell的算术运算符号
shell 算术运算命令
用于数学运算的命令:
echo $((9>8))
echo $((8>7&&6>5))
echo $((8>9&&8>9))
echo $((100>101&&8>9))
echo $((10/3))
echo $((6**2))
echo $((7%3))
shell 的计算支持整数的变量计算
结合变量计算:
num=5
((num=num**2))
echo $num
[wei@qwei ~]$ num=5
[wei@qwei ~]$ ((num=num**2))
[wei@qwei ~]$ echo $num
25
[wei@qwei ~]$ num=100
[wei@qwei ~]$ ((num=num**3))
[wei@qwei ~]$ echo $num
1000000
[wei@qwei ~]$
变量赋予在双括号之内
[wei@qwei ~]$ ((a=2+2**4+8))
[wei@qwei ~]$ echo $a
26
不使用变量接受,我们需要加上$符号接收数值。不然就会报错。
echo $((7**2+8))
57
数值计算的脚本开发
怎么做数值计算的脚本开发
++ / -- 两个符号
++ 加1
-- 减1
++a :先计算+1,再赋值给a
a++ : 先对变量操作,再进行+1
脚本开发,该脚本开发会用到脚本shell函数
脚本开发:
第一步:脚本开发的功能,以及需求
第二步:转换为shell编程语言完成这个功能
功能:开发一个接受用户的输入的数字,并且对运算符号进行判断,最终得到一个计算的脚本文件。
完成用户输入
会用户输入数值进行判断
对运算符号进行判断
对结果进行打印
计算
vim calaulation.sh
#!bin/bash
echo $($1)
bash calculation.sh
let 命令计算
对于脚本开发每个都有自己的想法,实现方案比较多。
使用let命令计算两个数值相加。
let命令的执行的效果等同于双括号
但是双括号计算数值计算更高。
let命令对变量的数值计算
bash原生语法不支持计算
num=5
let num=num+5
echo $num
开发nginx 存活检测脚本
vim check_nginx_status.sh
#/bin/bash
脚本开发的思路:
第一确定需求的功能和思路,先定义变量,用于存储变化的值,便于后期维护
第二步:编写伪代码
第一步:
nginx_version=1.7
第二步:安装服务
yum install nginx-${nginx_versin}
第三步:启动服务
systemctl start nginx
第四步:修改配置文件
第五步:重启服务
介绍一下nginx web服务
nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;nginx可以作为一个HTTP服务器进行网站的发布处理,另外nginx可以作为反向代理进行负载均衡的实现。
expr命令,bc命令 awk命令 进行数学运算
expr命令的使用
expr --help 查看该命令的使用指南
实践:
[wei@qwei ~]$ expr 5+3
5+3
[wei@qwei ~]$ expr 5 + 3
8
[wei@qwei ~]$ # expr 并不是特别好用,基于空格传入参数,但是在shell里面一些元字符都是有特殊含义
[wei@qwei ~]$ expr 5 \* 9
45
[wei@qwei ~]$
[wei@qwei ~]$ # 求长度
[wei@qwei ~]$ expr length 123435456
9
[wei@qwei ~]$ # 逻辑判断
[wei@qwei ~]$ expr 7 \> 0
1
[wei@qwei ~]$ expr 7 \> 10
0
[wei@qwei ~]$ #expr 模式匹配
[wei@qwei ~]$ # expr 支持模式匹配的功能
[wei@qwei ~]$ # : 计算字符串的字符数量
[wei@qwei ~]$ # .* : 任意的字符串重复0次或者多次
[wei@qwei ~]$ expr 私服出巡 ":" ".*"
12
[wei@qwei ~]$ expr 私服出巡 ":" ".*k"
0
[wei@qwei ~]$
判断jpg文件的字符个数
expr yc.png ":" ".*\.jpg"
[wei@qwei ~]$ expr yc.png ":" ".*\.png"
6
bc 命令的使用
[wei@qwei ~]$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
2 + 2
4
3 - 1
2
5/2
2
8/2
4
3*4
12
4 * 7
28
2.22 *17
37.74
^C
(interrupt) Exiting bc.
# 结合管道符号
[wei@qwei ~]$ echo "4*4"| bc
16
[wei@qwei ~]$ echo "18/2"|bc
9
[wei@qwei ~]$ echo "2.5*2"|bc
5.0
[wei@qwei ~]$ echo "4*4"| bc
16
[wei@qwei ~]$ echo "18/2"|bc
9
[wei@qwei ~]$ echo "2.5*2"|bc
5.0
# 结合变量
[wei@qwei ~]$ num=5
[wei@qwei ~]$ res=`echo $num*4|bc`
[wei@qwei ~]$ echo $res
20
计算1~1000之和
vim cal.sh
在vim文件中进行操作
#!/bin/bash
从python 语言实现;
我们可以使用一次for 循环
sum = 0
for i in range(1, 1001):
sum += i
print("打印从1加到1000的:", sum)
我们使用shell 如何实现:
脚本开发:
tr 命令进行替换
echo {1..1000} | tr " " "+"
生成序列:
seq 1000
seq -s "+" 1000
echo ${1..1000}| tr " " "+" | bc
[wei@qwei ~]$ echo {1..100} | tr " " "+" | bc
5050
[wei@qwei ~]$ echo {1..1000} | tr " " "+" | bc
500500
[wei@qwei ~]$ seq -s "+" 100 | bc
5050
[wei@qwei ~]$ seq -s "+" 1000 | bc
500500
[wei@qwei ~]$
# awk 语法实现
[wei@qwei ~]$ echo "7 9" | awk '{print($1+$2)}'
16
# $[]
相似命令是: 'rec'
[wei@qwei ~]$ res=$[9*8]
[wei@qwei ~]$ echo $res
72
shell 的条件判断
test 条件测试
test命令是一个表达式,他的结果是真,还是假,如果条件为真,那么命令执行状态码的结果就是为0,否则就不是0
test 命令
-e 判断文件是否存在,是普通文件或者目录
[wei@qwei ~]$ ls
file.sh length_word.sh LR make_vars.sh nohup.out sub_str test_date.sh 公共 模板 视频 图片 文档 下载 音乐 桌面
[wei@qwei ~]$ test -e file.sh
[wei@qwei ~]$ echo $?
0
test 语法大全
test命令实践
test 命令
test 测试参数 测试对象 对结果进行判断执行的逻辑动作
[wei@qwei ~]$ #判断文件是否存在,不存在判断一些动作
[wei@qwei ~]$ #创建一个文件 touch
[wei@qwei ~]$ #我们应该先使用条件测试
[wei@qwei ~]$ # 写脚的开发,我们在开发的时候,应该测试文件是否已经创建,而不应该创建文件夹或者文件。
[wei@qwei ~]$ vim file_mkdir.sh
[wei@qwei ~]$ bash file
file_mkdir.sh file.sh
[wei@qwei ~]$ bash file
file_mkdir.sh file.sh
[wei@qwei ~]$ bash file
/usr/bin/file: /usr/bin/file: 无法执行二进制文件
[wei@qwei ~]$
[wei@qwei ~]$
[wei@qwei ~]$
[wei@qwei ~]$ bash file_mkdir.sh
脚本执行创建文件夹
已经正确执行完毕
[wei@qwei ~]$ ls
file_mkdir.sh file.sh length_word.sh LR make_vars.sh nohup.out sub_str test test_date.sh 公共 模板 视频 图片 文档 下载 音乐 桌面
[wei@qwei ~]$ test -e test && echo "该文件已经存在"
该文件已经存在
[wei@qwei ~]$ bash file_mkdir.sh
脚本执行创建文件夹
mkdir: 无法创建目录"test": 文件已存在
已经正确执行完毕
我们在执行脚本之前需要对所创建的文件进行判断
test -e 所创建的文件 && echo "该文件已经创建不再创建"
test命令 其他参数使用
test -f 判断是否是普通话文件用法
test -d 判断是否是目录类型用法
test -z 判断字符串为空,就为真,否则为假
test -n 判断字符串为空,就为假,否则为真
条件测试中括号详解
脚本中经常使用的脚本测试
test 和[] 必须一样的
如何使用[]括号进行测试
使用变量替换的玩法实现测试
注意:在条件测试中使用变量,必须加上双引号
[ -n "$filename" ]
中括号测试实践
应该怎么玩中括号的?来进行测试
为什么要进行测试:
在脚本开发的时候,我们需要进行先通过测试来判断文件是否存在,
以及我们是否有文件的修改权限,以及文件的添加权限,
不希望这个错误发生在脚本开发的过程中,
所以我们需要进行条件测试,然后在进行叫脚本的开发。
达到事半功倍的结果。所以怎么写好条件测试,是脚本开发中重要的问题。
变量测试
字符串测试
字符串测试:
处理日志,部署网站。
比较两个字符串中的值,是否相等,不等于的情况。
= 判断是否相等
!= 判断不等于
! 结果的反义
字符串比较
[root@qwei wei]# [ "bao" = "bao" ] && echo ok || echo no
ok
#变量的使用
[root@qwei wei]# name="baoqiwei"
[root@qwei wei]# [ "${name}" = "baoqowei" ] && echo ok || echo no
no
[root@qwei wei]# [ "${name}" = "baoqiwei" ] && echo ok || echo no
ok
[root@qwei wei]# var="chen"
[root@qwei wei]# [ "${var}" = "chen" ] && echo "匹配正确" || "匹配错误"
匹配正确
[root@qwei wei]#
判断文件是否存在,不存在显示no
[root@qwei wei]# [ -f "hello.txt" ] && echo ok || echo no
no
判断文件是否存在,不存在显示ok
[root@qwei wei]# [ ! -f "hello.txt" ] && echo ok || echo no
ok
数值比较
1
[root@qwei wei]# [ 8 > 1 ] && echo ok || echo no
ok
[root@qwei wei]# [ 8 < 1 ] && echo ok || echo no
ok
[root@qwei wei]# [ 8 \ < 1 ] && echo ok || echo no
bash: [: 8: 期待一元表达式
no
[root@qwei wei]#
注意数学符号的时候,需要使用\ 转义字符进行判断,不然返回的结果会报错。
[root@qwei wei]# [ 3 -lt 4 ] && echo ok || echo no
ok
[root@qwei wei]# [ 3 -gt 4 ] && echo ok || echo no
no
[root@qwei wei]# [ 3 -ge 4 ] && echo ok || echo no
no
[root@qwei wei]# [ 8 -ge 4 ] && echo ok || echo no
ok
[root@qwei wei]# [ 8 -ge 8 ] && echo ok || echo no
ok
[root@qwei wei]# [ 8 -le 8 ] && echo ok || echo no
ok
[root@qwei wei]# [ 8 -eq 8 ] && echo ok || echo no
ok
[root@qwei wei]# n1=98;n2=99
[root@qwei wei]# test ${n1} -lt ${n2} && echo ok || echo no
ok
[root@qwei wei]#
逻辑操作运算符
&& -a 与运算
|| -o 或运算
中括号[ ] 和test使用的操作符
实战:
[wei@qwei ~]$ file1=/etc/init.d/network
[wei@qwei ~]$ file2=/etc/hostname
[wei@qwei ~]$ echo ${file1} ${file2}
/etc/init.d/network /etc/hostname
[wei@qwei ~]$ [ -f "$file1" -a -f "$file2" ] && echo ok || echo no
ok
[wei@qwei ~]$ [ -f "$file1" -a -f "$file2" ] && echo ok || echo no
ok
[wei@qwei ~]$ [ -f "$file1" -o -f "$file2" ] && echo ok || echo no
ok
test -n 判断字符串是否为空
[wei@qwei ~]$ a=""
[wei@qwei ~]$ b="ok"
[wei@qwei ~]$ test -n "$a" && echo yes || echo no
no
[wei@qwei ~]$ test -n "$b" && echo yes || echo no
yes
[wei@qwei ~]$
逻辑运算脚本实战开发,我们需要对一个需求进行脚本开发。后续会使用一百个脚本开发的脚本代码。针对用户的需求。进行脚本开发。
脚本的统一管理:
cd /shell_program/ 这个目录是作为脚本的统一管理。当我们需要创建新的目录时候,我们就需要在一个目录中创建脚本,方便我们后期的维护。在Linux系统中我们一般都会使用shell_program 这个目录下做脚本管理。
shell函数中if语句开发
单分支语句:
if <条件表达式>
then
code
fi
简化:
if <条件表达式>;then
code
fi
双分支语句:
嵌套语句:
if <条件表达式>
then
code ....
if <条件表达式>
then
code....
fi
fi
多分支 条件判断
if <条件表达式>
then
code1
elif <条件表达式>
then
code2
else
then
单分支if实战
if嵌套
开发一个检测内存监控的脚本
开发nginx mysql服务监控脚本是否正常运行
开发rsync启停脚本
#######单分支if开发
if结合条件测试语句脚本开发
#!/bin/bash
if [ -f /etc/hosts ]
then
echo "该文存在"
fi
if [[ -f /etc/hosts ]]
then
echo "[[]] is ok"
fi
if test -f /etc/hosts
then
echo "test is ok"
fi
[wei@qwei scripts]$ vim if_1.sh
[wei@qwei scripts]$ bash if_1.sh
该文存在
[[]] is ok
test is ok
开发系统监控脚本
需求:
1检测linux 可用内存当可用内存小于100M就发邮件给运维
2并在在该脚本中加入crontab ,每三分钟检测一次内存
思路:
1获取当前内存情况
2 配置邮件的告警,用linux发送邮件,邮件内容是当前内存射剩余情况
3 开发脚本获取内存情况,判断剩余的内存
4 脚本加入crontab 写入规则
看内存的命令:
free -m
单分支脚本
[wei@qwei scripts]$ vim if_read.sh
[wei@qwei scripts]$ cat if_read.sh
#!/bin/bash
a=$1
b=$2
if [ "$a" -lt "$b" ]
then
echo "yes, $a less than $b"
exit 0
fi
if [ "$a" -eq "$b" ]
then
echo "yes,$a equal $b"
exit 0
fi
if [ "$a" -gt "$b" ]
then
echo "yes, $a grahter than $b"
exit 0
fi
[wei@qwei scripts]$ bash if_read.sh 3 4
yes, 3 less than 4
[wei@qwei scripts]$ bash if_read.sh 6 6
yes,6 equal 6
[wei@qwei scripts]$ bash if_read.sh 82 9
yes, 82 grahter than 9
[wei@qwei scripts]$
多分支的脚本
实现多分支
[wei@qwei scripts]$ bash if_read2.sh 4 6
yes, 4 less than 6
[wei@qwei scripts]$ bash if_read2.sh 8 8
yes, 8 equal 8
[wei@qwei scripts]$ bash if_read2.sh 9 5
yes 9 greater than 5
[wei@qwei scripts]$ cat if_read2.sh
#!/bin/bash
a=$1
b=$2
if [ "$a" -lt "$b" ]
then
echo "yes, $a less than $b"
elif [ "$a" -eq "$b" ]
then
echo "yes, $a equal $b"
else
echo "yes $a greater than $b"
fi
MySQL 监控命令
端口监控:
命令:在服务端监控服务端口常见命令:netstat,ss,lsof
远程监控服务器本地端口的命令:telnet nmap,nc
监控服务进程或者进程数:
ps -ef|grep nginx|wc -l
ps -ef|grep mysql|wc -l
#本地监控mysql
netstat -tunlp|grep mysql|wc -l
0
ss -tunlp|grep mysql | wc -l
0
#远程监控mysql
namp 命令实现远程监控
telnet 命令
###shell 脚本实战编程
定义函数
sayHello(){
echo "他好,你好,才是真的好"
}
调用函数,执行函数
sayHello
shell函数的好处:
1shell 函数开发的特点类似于alias别名一样,能够简化Linux命令的操作,让整个命令更加简介,函数体必须还有一个函数名称。
2使用函数的可以简化流程,简化函数版本定义和使用
3使用函数将相同的程序,定义封装成一个函数,可以减少程序代码的数量,提高开发的效率。
4使用函数可以写更少的代码,提高代码的复用性。
5函数可以增加程序的可读性,易读性,容易管理和维。
shell函数定义的语法
标准的函数定义:
定义一个function 函数名称(){
函数体
执行的操作,执行的Linux命令
return
}
#当使用后function 可以省略括号
function 函数名{
函数体
执行的Linux命令
return
}
函数名(){
函数体
执行的linux命令
return
}
执行函数的基础概念
执行函数有一些概念需要知道
函数必须先定义后执行
函数体内定义的变量,是局部变量,只有在函数中才可以调用
函数体外部定义的变量 是全局变量
return 和exit不一样
return 是结束函数的执行,返回一个退出值
exit 是结束shell环境,返回一个返回值给当前的shell环境
函数如果想单独写入一个文件,只可以使用source
函数内, 使用local 关键字,定义局部变量
func(){
echo "这是一个定义的函数"
}
func 执行这个函数
处理新传入进来的变量
实现结果:
[wei@qwei scripts]$ bash func1.sh 1 2 3
传入进来的脚本参数,依次是1, 2, 3 ,并且参数一共是3
[wei@qwei scripts]$ # 第一个函数脚本
[wei@qwei scripts]$ cat my_func.sh
#!/bin/bash
func(){
echo "这是一个定义的函数"
}
#新函数,处理脚本新传进来的参数
paramter(){
echo "传入进来的脚本参数,依次是$1, $2, $3 ,并且参数一共是$#"
}
[wei@qwei scripts]$ #第二个函数脚本
[wei@qwei scripts]$ cat func1.sh
#!/bin/bash
[ -f ~/shell_program/scripts/my_func.sh ] && . ~/shell_program/scripts/my_func.sh || exit
#执行测试,判断该文件是否存在,存在就该脚本加载到shell环境中。
paramter $1 $2 $3
[wei@qwei scripts]$ #调用func1.sh函数去执行my_func函数脚本中paramter 函数处理新的传进来的参数
函数脚本开发:
检测网站的存活脚本开发
1给脚本传入参数,检测url是否正常
2基于函数开发的形式
非函数检测;
vim check_url.sh
#在脚本文件中写入这些命令
#执行方式 bash check_url.sh www.pythonav.cn
if [ "$#" -ne 1 ]
then
echo "Usage: $0 url"
exit 1
fi
# 利用wget命令测试url是否正常
wget --spider -q -o /dev/null --tries=1 -T 5 $1
#对状态码进行判断网站是否正常
if [ "$?" -eq 0 ]
then
echo "$1 is running"
else
echo "$1 is done"
fi
[wei@qwei scripts]$ bash check_url.sh www.pythonav.cn
www.pythonav.cn is done
shell编程实战
#!/bin/bash
# 实时监控本机内存和硬盘剩余空间,剩余内存小于500M、根分区剩余空间小于1000M时,发送报警邮件给root管理员
# 提取根分区剩余空间
disk_size=$(df / | awk '/\//{print $4}')
# 提取内存剩余空间
mem_size=$(free | awk '/Mem/{print $4}')
while :
do
# 注意内存和磁盘提取的空间大小都是以 Kb 为单位
if [ $disk_size -le 512000 -a $mem_size -le 1024000 ]
then
mail ‐s "Warning" root <<EOF
Insufficient resources,资源不足
EOF
fi
done
#!/bin/bash
# 生成签名私钥和证书
read -p "请输入存放证书的目录:" dir
if [ ! -d $dir ];then
echo "该目录不存在"
exit
fi
read -p "请输入密钥名称:" name
# 使用 openssl 生成私钥
openssl genrsa -out ${dir}/${name}.key
# 使用 openssl 生成证书 #subj 选项可以在生成证书时,非交互自动填写 Common Name 信息
openssl req -new -x509 -key ${dir}/${name}.key -subj "/CN=common" -out ${dir}/${name}.crt