shell 介绍
一、什么是shell
shell是一个程序,采用C语言编写,是用户和linux内核沟通的桥梁。它既是一种命令语言,又是一种解释性的编程语言。通过一个图表来查看一下shell的作用。
作用:
kernel:为软件服务,接收用户或软件指令驱动硬件,完成工作
shell:命令解释器
user:用户接口,对接用户。
二、shell 功能
命令行解释功能
启动程序
输入输出重定向
管道连接
文件名置换 (echo /*)
变量维护
环境控制
shell编程
shell 语法
如何抒写一个shell脚本
shell脚本运行
shell中的特殊符号
重定向
shell中数学运算
shell脚本就是一组命令的集合,按照先后顺序执行;自上而下写入到一个文本文件中,然后给予执行权限。
一、如何抒写一个shell脚本
shell脚本的命名
名字要有意义,最好不要用a、b、c、d、1、2、3、4这种方式命名;虽然linux系统中,文件没有扩展名的概念,依然建议你用.sh结尾;名字不要太长,最好能在30个字节以内解决。例如:check_memory.sh
shell脚本格式
shell脚本开头必须指定脚本运行环境 以 #!这个特殊符号组合来组成。如: #!/bin/bash 指定该脚本是运行解析由/bin/bash来完成的;
1 2 3 4 5 6 7 8 9 shell脚本中,最好加入脚本说明字段 。。。 。。。 。。。
二、如何运行一个shell脚本 1 2 3 4 5 6 7 8 9 10 11 [root@lemon ~] /bin/sh /bin/bash /usr/bin/sh /usr/bin/bash 脚本运行需要执行权限,当我们给一个文件赋予执行权限后,该脚本就可以运行。 [root@lemon ~] 如果不希望赋予脚本执行权限,那么可以使用bash命令来运行未给予执行权限的脚本bash fiename [root@lemon ~]
三、shell中的特殊符号 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ~ 家目录,cd ~ 代表进入用户家目录 ! 执行历史命令,!! 执行上一条命令 $ 变量中取内容符 + - * / % 对应数学运算 加 减 乘 除 取余 * 星号是shell中的通配符 匹配所有 ? 问号是shell中的通配符 匹配除回车以外的一个字符 \ 转义字符 `` 反引号,命令中执行命令 ' ' 强转义,禁止引用其他变量值,$视为普通字符;意思就是' ' 号里面写的是什么,显示的就是什么" " 弱转义,允许通过$符号引用其他变量值;意思就是将" " 号里面变量名的变量值显示出来| 管道符,把前边命令的输出结果,作为后边命令的处理对象 || 逻辑或,前边的命令执行成功,后面的不执行;前边的命令执行失败,后面的命令将会被执行 & 后台执行,仅在当前终端生效,断开终端后放在后台运行的进程也会随着退出 && 逻辑与,只有前边的命令执行成功,才会执行后面的命令 ; 和 && 符号不同的一点就是 他不管前面命令的结果是否成功,它都会执行后面命令
四、shell重定向 1 2 3 4 5 6 7 1> 重定向正确覆盖;把屏幕上的正确内容输出到文件 1>> 重定向正确追加;把屏幕上的正确内容以追加的形式输出到文件 2> 重定向错误覆盖;把屏幕上的错误内容输出到文件 2>> 重定向错误追加;把屏幕上的错误内容以追加的形式输出到文件 &> 重定向混合覆盖;把屏幕上无论是正确还是错误的都输出到文件 &>> 重定向混合追加;把屏幕上无论是正确还是错误以追加的形式都输出到文件
五、shell数学运算 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 [root@lemon ~] 103 [root@lemon ~] 97 [root@lemon ~] 300 [root@lemon ~] 33 [root@lemon ~] 1 [root@lemon ~] 1000000 [root@lemon ~] 2 [root@lemon ~] 3 [root@lemon ~] 10 [root@lemon ~] 2 [root@lemon ~] 103 [root@lemon ~] 97 [root@lemon ~] 300 [root@lemon ~] 33.33
shell格式化输出
一个程序需要有0个或以上输入,一个或更多输出
一、echo 命令介绍
功能:将内容输出到默认显示设备
echo命令的功能是在显示器上显示一段文字,一般起到一个提示的作用。 功能说明:显示文字。
补充说明:echo会将输入的字符串送往标准输出。输出的字符串间以空白字符隔开,并在 最后加上换行号。
命令选项:
举例说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [root@lemon ~] lemon handsome [root@lemon ~] lemon handsome [root@lemon ~] lemon[root@lemon-min ~] [root@lemon ~] nhandsome [root@lemon ~] lemon handsome
二、颜色代码
脚本中echo显示内容带颜色显示,echo显示带颜色,需要使用参数 -e
示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 下面是相应的字和背景颜色,可以自己来尝试找出不同颜色搭配 echo -e "\033[31m 红色字 \033[0m" echo -e "\033[34m 黄色字 \033[0m" echo -e "\033[41;33m 红底黄字 \033[0m" echo -e "\033[41;37m 红底白字 \033[0m" 字颜色:30—–37 echo -e "\033[30m 黑色字 \033[0m" echo -e "\033[31m 红色字 \033[0m" echo -e "\033[32m 绿色字 \033[0m" echo -e "\033[33m 黄色字 \033[0m" echo -e "\033[34m 蓝色字 \033[0m" echo -e "\033[35m 紫色字 \033[0m" echo -e "\033[36m 天蓝字 \033[0m" echo -e "\033[37m 白色字 \033[0m" 字背景颜色范围:40—–47 echo -e "\033[40;37m 黑底白字 \033[0m" echo -e "\033[41;37m 红底白字 \033[0m" echo -e "\033[42;37m 绿底白字 \033[0m" echo -e "\033[43;37m 黄底白字 \033[0m" echo -e "\033[44;37m 蓝底白字 \033[0m" echo -e "\033[45;37m 紫底白字 \033[0m" echo -e "\033[46;37m 天蓝底白字 \033[0m" echo -e "\033[47;30m 白底黑字 \033[0m" 最后面控制选项说明 \033[0m 关闭所有属性 \033[1m 设置高亮度 \033[4m 下划线 \033[5m 闪烁 \033[7m 反显 \033[8m 消隐 设置前景色 \033[40m — \33[47m 设置背景色 \033[nA 光标上移n行 \033[nB 光标下移n行 \033[nC 光标右移n行 \033[nD 光标左移n行 \033[y;xH设置光标位置 \033[2J 清屏 \033[K 清除从光标到行尾的内容 \33[s 保存光标位置 \033[u 恢复光标位置 \033[?25l 隐藏光标 \033[?25h 显示光标
shell交互输入定义变量 一、read基本命令
默认接受键盘的输入,回车符代表输入结束
read 命令选项:
-p 打印信息
-t 交互停留的时间
-s 隐藏在外面输入值的信息
-n 限制输入字符个数
二、read 基本示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@lemon ~] clear echo "Centos linux 7 (Core)" echo -e "Kernel `uname -r` an `uname -m`" read -n 6 -p "login:" userread -n 6 -t 10 -s -p "Passd:" passwdecho echo -e "login:$user \nPassd:$passwd " [root@lemon ~] Centos linux 7 (Core) Kernel 3.10.0-693.el7.x86_64 an x86_64 login:lemon Passd: login:lemon Passd:123123
变量
一、变量介绍 1 在编程中,我们总有一些数据需要临时存放在内存,以待后续使用时快速读出。内存在系统启动的时候被按照1 B一个单位划分为若干个块,然后统一编号,并对内存的使用情况做记录,保存在内存跟踪表中。
1 2 3 4 5 6 7 8 9 10 11 12 13 计算机的单位: 1B=8bit 1KB=1024B 1MB=1024KB 1GB=1024MB 1TB=1024GB 1PB=1024TB 1EB=1024PB 1ZB=1024EB ... 好了,已经够大了!当然还有YB、BB更大的单位,同样进制也是1024. 1G=1024*1024*1024=1073741824B
假如你将一个1B的字符存入内存,如何读出呢?有没有一种大海捞针的感觉啊!我们讨论一下计算机是如何通过让我们快速将数据存在内存,如何从内存中读出数据的。我们研究过变量后就明白了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 1)0X5...0X8(物理地址) <===> STRING1(逻辑地址) <===> 存取数据(ABC) 0x5...0x8是内存物理地址,是计算机寻址的依据; STRING1是给人看的,方便人记忆; 2)对于人来说STRING1上存的数据是ABC,对于计算机来说数据是存在物理地址上的; 3)在建立变量的时候计算机自动将逻辑地址(变量名)和物理地址做了对应。 1)当调用STRING1的时候,计算机会根据对应关系,找到物理地址 2)定位内存地址,读出数据并返回
二、变量分类
注意事项:一定要按顺序写位置变量名!比如:$1 $2 $3 $4 $5 $6,如果位置变量用到两位数或多位数的话就用{}括上;比如:echo ‘$10 是’ ${10};如果不加就会出现问题!
本地变量: 用户私有变量,只有本用户可以使用,保存在家目录下的.bash_profile、.bashrc文件中
全局变量: 所有用户都可以使用,保存在/etc/profile、/etc/bashrc文件,可使用 export
命令查看系统变量
用户自定义变量: 用户自定义,比如脚本中的变量
位置变量: 可以放在任何位置的变量,$1、$2、$3……
案例解释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [root@lemon ~] echo '我是$1:' $1 echo '我是$2:' $2 echo '我是$3:' $3 echo '我是$4:' $4 echo '我是$5:' $5 echo '我是$6:' $6 echo '我是$7:' $7 echo '我是$8:' $8 echo '我是$9:' $9 echo '我是$10:' ${10} [root@lemon ~] 我是$1 : q 我是$2 : w 我是$3 : e 我是$4 : r 我是$5 : t 我是$6 : y 我是$7 : u 我是$8 : i 我是$9 : o 我是$10 : p
预定义变量: $0、$#、$*、$?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [root@lemon ~] echo "我是-->$1 " echo "我是-->$2 " echo "我是-->$3 " echo '==================================' for i in "$*" ;do echo "$i " done echo '==================================' for y in "$@ " ;do echo "$y " done echo '==================================' [root@lemon ~] 我是-->a1 我是-->a2 我是-->a3 ================================== a1 a2 a3 ================================== a1 a2 a3 ==================================
案例解释:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@lemon ~] echo "我是-->$1 " echo "我是-->$2 " echo "我是-->$3 " echo "$?" echo "$# " echo "$*" echo "$0 " [root@lemon ~] 我是-->a1 我是-->a2 我是-->a3 0 3 a1 a2 a3 envd.sh
三、使用变量 1. 定义变量
变量格式: 变量名=值
在shell编程中的变量名和等号之间不能有空格。
变量名命名规则:
1 2 3 [root@lemon ~] [root@lemon ~]
2. 读取变量内容
1 2 3 4 5 [root@lemon ~] lemon [root@lemon ~] 12345
3. 取消变量 unset 1 2 [root@lemon ~] [root@lemon ~]
4. 定义全局变量 export
上述设置的变量其实都是一次性的变量,系统重启就会丢失。
如果希望本地变量或者全局变量可以永久使用,可以将需要设置的变量写入变量文件中即可。
5. 定义永久变量
1 2 3 4 5 6 7 8 9 [root@lemon ~] export name='lemon' [root@lemon ~] [root@lemon ~] export age=18[root@lemon ~]
数组
一、数组介绍
二、基本数组
数组可以让用户一次赋予多个值,需要读取数据时只需通过索引调用就可以方便读出了。
1. 数组语法 1 2 数组名称=() 数组名称=(元素1 元素2 元素3 ...)
2. 数组读出 1 2 ${数组名称[索引]} 索引默认是元素在数组中的排队编号,默认第一个从0 开始
3. 数组赋值
数组赋值格式:数组名[下标]=值,下标不存在,则新增数组元素; 下标已有,则覆盖值。
方法1:一次赋一个值 1 2 [root@lemon ~] [root@lemon ~]
方法2:一次赋多个值 1 2 [root@lemon ~] [root@lemon ~]
4. 查看基本数组-a
5. 访问数组元素 1 2 3 4 5 6 [root@lemon ~] [root@lemon ~] [root@lemon ~] [root@lemon ~] [root@lemon ~] [root@lemon ~]
6. 遍历数组
1 2 3 4 5 [root@lemon ~] pear apple orange peach
三、关联数组 1. 定义关联数组
1 2 [root@lemon ~] [root@lemon ~]
2. 关联数组赋值 方法1:一次赋一个值 1 2 3 4 [root@lemon ~] [root@lemon ~] [root@lemon ~] [root@lemon ~]
方法2:一次赋多个值
3. 查看关联数组-A
4. 访问数组元素
@ 等同于 *
1 2 3 4 [root@lemon ~] [root@lemon ~] [root@lemon ~] [root@lemon ~]
5. 遍历数组 1 2 3 4 5 [root@lemon ~]# for i in `echo ${ass_array2[*]}` ;do echo $i; done tool tom jack alice
6. 简单的学员信息系统 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #!/bin/bash for ((i=0;i<3;i++));do read -p "输入第$((i + 1) )个人名: " name[$i ] read -p "输入第$[$i + 1]个年龄: " age[$i ] read -p "输入第`expr $i + 1`个性别: " gender[$i ] echo done clear echo -e "\t\t\t\t\t\t学员查询系统" while true ;do cp=0 read -p "输入要查询的姓名: " xm [ $xm == "q" ] && exit for ((i=0;i<3;i++));do if [ "$xm " == "${name[$i]} " ];then echo -e "name: ${name[$i]} \nage: ${age[$i]} \ngender: ${gender[$i]} " cp=1 fi done [ $cp -eq 0 ]&&echo "not found student" done
shell流程控制-if判断语句
shell中的四大运算
if语法
在写程序的时候,时常会对上一步执行是否成功如何判断苦恼,当我们今天学习了if就可以解决你的苦恼。
if语句在我们程序中就是用来做判断的,不管学习的是什么语言,以后只要涉及到判断的部分,都可以直接拿if来使用,不同的语言之间的if只是语法不同,原理是相同的。
一、shell中的运算 1. 数学比较运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 -eq [root@lemon ~] 1 [root@lemon ~] 0 -gt [root@lemon ~] 1 [root@lemon ~] 0 -lt [root@lemon ~] 0 [root@lemon ~] 1 -ge [root@lemon ~] 1 [root@lemon ~] 0 [root@lemon ~] 0 -le [root@lemon ~] 0 [root@lemon ~] 0 [root@lemon ~] 1 -ne [root@lemon ~] 0 [root@lemon ~] 1 [root@lemon ~] 0
2. 字符串比较运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 == [root@lemon ~] 0 [root@lemon ~] 1 != [root@lemon ~] 1 [root@lemon ~] 0 -z [root@lemon ~] lemon [root@lemon ~] [root@lemon ~] 1 [root@lemon ~] 0 [root@lemon ~] 0 [root@lemon ~] 1
3. 文件比较与检查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 -e [root@lemon ~] 0 [root@lemon ~] 0 [root@lemon ~] 1 [root@lemon ~] 1 -d [root@lemon ~] 0 [root@lemon ~] 1 -f [root@lemon ~] 0 [root@lemon ~] 1 -nt [root@lemon opt] -rw-r--r-- 1 root root 0 6月 5 21:21 lemon.txt -rw-r--r-- 1 root root 0 6月 5 21:28 tools.txt [root@lemon opt] 1 [root@lemon opt] 0 -ot [root@lemon opt] -rw-r--r-- 1 root root 0 6月 5 21:21 lemon.txt -rw-r--r-- 1 root root 0 6月 5 21:28 tools.txt [root@lemon opt] 0 [root@lemon opt] 1 -s [root@lemon ~] 0 [root@lemon ~] 0 [root@lemon ~] 1 [root@lemon ~] 1 -O 测试省略…… -G 测试省略…… -r 测试省略…… -w 测试省略…… -x 测试省略……
4. 逻辑运算
逻辑运算注意事项:
逻辑与 或 运算都需要两个或以上条件,逻辑非运算只能一个条件。
口诀:
逻辑与运算 <==> 真真为真 真假为假 假假为假
逻辑或运算 <==> 真真为真 真假为真 假假为假
逻辑非运算 <==> 真为假 假为真
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 && [root@lemon ~] 0 [root@lemon ~] 1 || [root@lemon ~] 0 [root@lemon ~] 0 [root@lemon ~] 1 ! [root@lemon ~] 1 [root@lemon ~] 0
二、if 语法 1. 语法一: 单if语句
1 2 3 if [ condition ];then #condition 值为true or false commands fi
1 2 3 4 如果条件为真 那么 执行commands代码块 结束
1 2 3 4 5 [root@lemon ~] if [ 10 -eq 10 ];then echo "hello world" fi
1 2 [root@lemon ~] hello world
2. 语法二: if-else语句
适用范围:两步判断,条件为真干什么,条件为假干什么。
1 2 3 4 5 if [ condition ];then commands1 else commands2 fi
1 2 3 4 5 6 如果条件为真 那么 执行commands1 代码块 否则 执行commands2 代码块 结束
1 2 3 4 5 6 7 8 [root@lemon ~] read -p "请输入数字:" numberif [ $number -eq 10 ];then echo "条件为真" else echo "条件为假" fi
1 2 3 4 5 6 7 [root@lemon ~]# bash if.sh 请输入数字:10 条件为真 [root@lemon ~]# bash if.sh 请输入数字:20 条件为假
3. 语法三: if-elif-else语句
适用范围:多于两个以上的判断结果,也就是多于一个以上的判断条件。
1 2 3 4 5 6 7 8 9 if [ condition 1 ];then commands1 elif [ condition 2 ];then commands2 ....... else commandsX fi
1 2 3 4 5 6 7 8 9 10 11 12 如果 条件1 为真 那么 执行代码块1 如果 条件2 为真 那么 执行代码块2 以此类推的N个条件及对应的执行代码块 否则 【以上所有条件中没有一个满足的】 执行代码块X 结束
1 2 3 4 5 6 7 8 9 10 [root@lemon ~] read -p "请输入数字:" numberif [ $number -eq 10 ];then echo "条件 1 为真" elif [ $number -gt 10 ];then echo "条件 2 为真" else echo "以上条件都为假" fi
1 2 3 4 5 6 7 8 9 10 11 [root@lemon ~] 请输入数字:9 以上条件都为假 [root@lemon ~] 请输入数字:10 条件 1 为真 [root@lemon ~] 请输入数字:11 条件 2 为真
三、if 高级应用
if 命令, 双圆括号, 双中括号 条件测试
循环脚本控制语句 特殊条件表达式
测试 continue、break、exit 语句的不同点
通俗点讲:break是立马跳出循环;continue是跳出当前条件循环,继续下一轮条件循环;exit是直接退出整个脚本
1 2 3 4 5 6 7 8 9 [root@lemon ~] for i in {1..5};do if [ $i -eq 3 ];then $1 fi echo "$i " done echo "循环体外命令"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@lemon ~] 1 2 4 5 循环体外命令 [root@lemon ~] 1 2 循环体外命令 [root@lemon ~] 1 2
1. sleep N 脚本执行到该步休眠N秒
1 2 3 4 5 6 [root@lemon ~] for i in `seq 9 -1 1`;do echo -n -e "倒计时: $i \r" sleep 1 done
2. continue 跳过循环中的某次循环
3. break 跳出循环继续执行后续代码
1 2 3 4 5 6 7 8 #!/bin/bash for i in {1..9};do if [ $i -eq 6 ];then break else echo "$i " fi done
1 2 3 4 5 6 [root@lemon ~] 1 2 3 4 5
break N 跳出某个循环,用在嵌套循环环境,从内循环到外循环依次编号为1-N
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [root@lemon ~] for (( i=1; i<5; i++ ));do echo "#loop $i " for ((;;)); do echo "haha" break 2 done sleep 3 done
4. exit 退出当前脚本
作用:直接退出脚本,循环体外的命令不会执行
代码如下
1 2 3 4 5 6 7 8 9 [root@lemon ~] for i in {1..9};do if [ $i == 5 ];then exit 2 else echo "$i " fi done
1 2 3 4 5 6 7 [root@lemon ~] 1 2 3 4 [root@lemon ~] 2
shell流程控制-for循环语句
脚本在执行任务的时候,总会遇到需要循环执行的时候,比如说我们需要脚本每隔五分钟执行一次ping的操作,除了计划任务,我们还可以使用脚本来完成,那么我们就用到了循环语句。
循环的优点:
节省内存 10M脚本 1M脚本 哪个更剩内存 完成同一个任务
结构更清晰
节省开发时间成本
一、for 循环介绍
1 很多人把for循环叫做条件循环,或者for i in 。其实前者说的就是for的特性,for循环的次数和给予的条件是成正比的,也就是你给5 个条件,那么他就循环5 次;后者说的是for的语法。
二、for语法 1. for 语法一 1 2 3 for i in value1 value2 ... ... ;do commands done
1 2 3 4 5 [root@lemon ~] for i in `seq 1 9`;do echo "number <==> $i " done
1 2 3 4 5 6 7 8 9 10 [root@lemon ~] number <==> 1 number <==> 2 number <==> 3 number <==> 4 number <==> 5 number <==> 6 number <==> 7 number <==> 8 number <==> 9
2. for语法二
来段代码理解一下,看下还是输出1-9
1 2 3 4 5 [root@lemon ~] for ((i=1;$i <10;i++));do echo "number <==> $i " done
1 2 3 4 5 6 7 8 9 10 [root@lemon ~] number <==> 1 number <==> 2 number <==> 3 number <==> 4 number <==> 5 number <==> 6 number <==> 7 number <==> 8 number <==> 9
for循环使用多个变量
1 2 3 4 5 [root@lemon ~] for ((a=0,b=9;$a <10;a++,b--));do echo "number <==> $a $b " done
1 2 3 4 5 6 7 8 9 10 11 [root@lemon ~] number <==> 0 9 number <==> 1 8 number <==> 2 7 number <==> 3 6 number <==> 4 5 number <==> 5 4 number <==> 6 3 number <==> 7 2 number <==> 8 1 number <==> 9 0
for 无限循环 使用((;;)) 条件可以实现无线循环
1 2 3 4 5 [root@lemon ~] for ((;;));do echo "hello world" done
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@lemon ~] hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world ……………………………
shell流程控制-while循环语句
while循环介绍
while循环语法
while实战
一、while循环介绍
1 当程序执行到while 语句时,首先会计算condition 的值,如果condition 的值为假,结束整个while 语句,如果表达式的值为真,则执行语句,执行完语句再去计算表达式的值,如果表达式的值还为真,则在执行语句.....直到表达式的值为假才会停止,否则一直循环。
二、while循环语法 1 2 3 while [ condition ];do #注意,条件为真while 才会循环,条件为假,while 停止循环 commands done
三、while实战 1. 跳板机脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #!/bin/bash lemon (){ contiue=$(pgrep -l -u jump|grep "bash" |awk '{print $1}' ) kill -9 $contiue } trap "" HUP INT QUIT TSTPwhile true do read -p "andmin: 1).input is sshd server:192.168.1.1; 2).input is sshd server:192.168.1.2; 3).Input to user exit's 192.168.1.3; what is to name's server:" num if [[ $num -eq 1 ]];then ssh root@192.168.1.1 elif [[ $num -eq 2 ]];then ssh root@192.168.1.2 elif [[ $num -eq 3 ]];then lemon else echo "$0 语法|1|2|3" sleep 2 fi done
2. 遍历文件内容
1 2 3 4 5 [root@lemon ~] while read i;do echo "$i " done < $1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [root@lemon ~] root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:999:997:User for polkitd:/:/sbin/nologin tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin chrony:x:998:996::/var/lib/chrony:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
3. 读出文件中的列,IFS指定默认的列分隔符
1 2 3 4 5 6 [root@lemon ~] IFS=$":" while read f1 f2 f3 f4 f5 f6 f7;do echo "$f1 $f2 $f3 " done < /etc/passwd
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@lemon ~] root x 0 bin x 1 daemon x 2 adm x 3 lp x 4 sync x 5 shutdown x 6 halt x 7 mail x 8 operator x 11 games x 12 ftp x 14 nobody x 99 systemd-network x 192 dbus x 81 polkitd x 999 postfix x 89 chrony x 998 sshd x 74
4. 批量创建用户 及 设置密码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #!/bin/bash password=$(echo $RANDOM |md5sum|cut -c 1-6) number=100 for user in lemon{1..100};do useradd $user while [ $number -ge 1 ];do echo $password |passwd --stdin $user &>/dev/null let number-- if [ $? -eq 0 ];then tail -100 /etc/passwd else echo "error" fi done done
until语句
一、until介绍
和 while正好相反,until是条件为假开始执行,条件为真停止执行。
二、until语法 1 2 3 until [ condition ];do commands代码块 done
三、案例
1 2 3 4 5 6 7 8 9 [root@lemon ~] init_num=10 until [ $init_num -gt 20 ] do echo $init_num init_num=$((init_num + 1 )) done
1 2 3 4 5 6 7 8 9 10 11 12 [root@lemon ~] 10 11 12 13 14 15 16 17 18 19 20
case多条件分支语句
一、case介绍
概述:根据变量的值,顺序匹配模式,匹配后执行命令并结束,如果没有匹配的模式,则执行默认命令,执行成功后退出,返回1,然后退出case
意思就是:下面的模式就是变量名的值,模式里面的命令都会执行;从第一个开始,直到最后一个结束;如果没有模式则默认执行exit退出脚本命令
二、case语法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 case 变量 in 模式1 ) 执行代码块1 ;; 模式2 ) 执行代码块2 ;; ...... *) 代表不是以上模式的值就执行 *) 执行的默认代码块;默认是exit 。 ;; esac 注意:每个代码块执行完毕要以;;结尾代表结束,case结尾要以倒过来写的esac来结束。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@lemon ~] case $1 in 1) echo haha ;; 2) echo hehe ;; 3) echo heihei ;; *) echo 'usage:|1|2|3|' ;; esac
1 2 3 4 5 6 7 8 9 10 [root@lemon ~] haha [root@lemon ~] hehe [root@lemon ~] heihei [root@lemon ~] usage:|1|2|3| [root@lemon ~] usage:|1|2|3|
三、shell特殊变量 1 2 3 4 5 6 7 8 9 $* $@ $# $ $- $$ $ $_ $N
shell函数
一、函数介绍
Shell函数类似于Shell脚本里面存放了一系列的指令,不过Shell的函数存在于内存,而不是硬盘文件,所以速度很快,另外,Shell还能对函数进行预处理,所以函数的启动比脚本更快。
shell允许将一组命令集 或 语句形成一个可用块,这些块称为shell函数。
说白了,函数就是将某一组shell命令封装成一个模块,想用的时候就用,不用就放在原地
函数的优点:
代码模块化,调用方便,节省内存
代码模块化,代码量少,排错简单
代码模块化,可以改变代码的执行顺序
二、函数的语法 1 2 3 4 5 6 7 8 9 10 11 语法一: 函数名 () { 代码块 [return N] } 语法二: function 函数名 { 代码块 [return N] }
解析: 所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。函数中的关键字“return”可以放到函数体的任意位置,通常用于返回某些值,Shell在执行到return之后,就停止往下执行,返回到主程序的调用行,return的返回值只能是0~256之间的一个整数,返回值将保存到变量“$?”中。
三、Shell函数的退出及删除
1 2 3 4 5 6 7 source 或 . 脚本 declare -f declare -F unset -f 函数名
四、函数的变量概念
全局变量:默认情况下,脚本中定义的任何变量都是全局变量,在函数外定义的变量可在函数内正常访问。
局部变量:函数内部使用全局变量可以用 ‘local 变量名=值’ 声明成局部变量,局部变量只能在函数体内生效。
五、函数的应用
1 2 print () { echo "lemon"
或者
1 2 3 function hello { echo "hello world" }
print 和 hello就是函数的名字,函数名字命名参考变量一节中的变量命名规则
定义好函数后,如果想调用该函数,只需通过函数名调用即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [root@lemon ~] N1 () {echo "world" } N2 () {echo "hello" } N3 () {echo "lemon is a very good" } N2 N1 N3 N3
1 2 3 4 5 [root@lemon ~] hello world lemon is a very good lemon is a very good
自动化交互 expect 详解 一、expect介绍
expect是一个自动化交互套件,主要应用于执行命令和程序时,系统以交互形式要求输入指定字符串,实现交互通信。
expect自动交互流程: spawn启动指定进程 <—> expect获取指定关键字 <—> send向指定程序发送指定字符 <—> 执行完成退出
使用场景: 在管理系统的多种情况下,会出现管理员手动输入字符,称为交互式,如下:
二、安装 expect 工具 1 2 3 4 5 6 [root@lemon ~] [root@lemon ~] expect version 5.45
三、expect常用命令 1 2 3 4 5 6 7 8 9 10 11 spawn expect send exp_send exp_continue send_user exit eof set puts set timeout interact
四、expect 基本语法 1 2 3 4 5 6 7 8 9 spawn linux命令 expect "关键字" expect { "*yes/no" { send "yes\r" ; exp_continue} "*password:" { send "$password \r" } } interact
五、expect 应用案例 案例1:expect自动交互ssh远程登录
需要两台虚拟机
主机一 :IP — 192.168.2.1 主机名 — lemon
主机二 :IP — 192.168.2.2 主机名 — docker
代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [root@lemon ~] /usr/bin/expect [root@lemon ~] set ip [lindex $argv 0]set password [lindex $argv 1]spawn ssh root@$ip expect { "*(yes/no)?" { send "yes\r" ; exp_continue } "*password:" { send "$password \r" } } interact
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [root@lemon ~] [root@lemon ~] [root@lemon ~] spawn ssh root@192.168.2.2 The authenticity of host '192.168.2.2 (192.168.2.2)' can't be established. ECDSA key fingerprint is SHA256:dSDdVALO14Vgdmr49RwTkRDyXrZHmCz1CUVlSf0fZrM. ECDSA key fingerprint is MD5:8e:75:d7:bc:9c:61:45:fc:0c:67:3b:3a:f6:db:fe:3c. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added ' 192.168.2.2' (ECDSA) to the list of known hosts. root@192.168.2.2' s password: Last login: Sat Jun 6 13:15:44 2020 from 192.168.2.1 [root@docker ~] [root@docker ~] ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.2.2 netmask 255.255.255.0 broadcast 192.168.2.255 inet6 fe80::20c:29ff:fe16:9fdd prefixlen 64 scopeid 0x20<link> ether 00:0c:29:16:9f:dd txqueuelen 1000 (Ethernet) RX packets 349 bytes 46800 (45.7 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 262 bytes 43941 (42.9 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@docker ~] 登出 Connection to 192.168.2.2 closed. [root@lemon ~]
案例2:expect自动交互式管理执行命令
需要两台虚拟机
主机一 :IP — 192.168.2.1 主机名 — lemon
主机二 :IP — 192.168.2.2 主机名 — docker
代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@lemon ~] set ip [lindex $argv 0]set user [lindex $argv 1]set password [lindex $argv 2]set order [lindex $argv 3]set timeout 10spawn ssh $user @$ip $order expect { "*(yes/no)?" { send "yes\r" ; exp_continue } "*password:" { send "$password \r" } } interact
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [root@lemon ~] [root@lemon ~] spawn ssh root@192.168.2.2 free -m root@192.168.2.2's password: total used free shared buff/cache available Mem: 976 145 572 6 258 643 Swap: 1023 0 1023 [root@lemon ~]# ./admin.exp 192.168.2.2 root 123123 "df -hT" spawn ssh root@192.168.2.2 df -hT root@192.168.2.2' s password: 文件系统 类型 容量 已用 可用 已用% 挂载点 /dev/mapper/centos-root xfs 18G 3.2G 15G 18% / devtmpfs devtmpfs 478M 0 478M 0% /dev tmpfs tmpfs 489M 0 489M 0% /dev/shm tmpfs tmpfs 489M 6.7M 482M 2% /run tmpfs tmpfs 489M 0 489M 0% /sys/fs/cgroup /dev/sr0 iso9660 4.3G 4.3G 0 100% /mnt /dev/sdb1 xfs 80G 33M 80G 1% /sdb1 /dev/sda1 xfs 1014M 125M 890M 13% /boot tmpfs tmpfs 98M 0 98M 0% /run/user/0
案例3:expect自动化下发脚本,执行脚本(结合案例2)
需要两台虚拟机
主机一 :IP — 192.168.2.1 主机名 — lemon
主机二 :IP — 192.168.2.2 主机名 — docker
代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@lemon ~] ping -c 3 127.0.0.1 [root@lemon ~] set ip [lindex $argv 0]set user [lindex $argv 1]set password [lindex $argv 2]set sfile [lindex $argv 3]set ddir [lindex $argv 4]set timeout 10spawn scp $sfile $user @$ip :$ddir expect { "*yes/no" { send "yes\r" ; exp_continue} "*password:" { send "$password \r" } } interact
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [root@lemon ~] [root@lemon ~] [root@lemon ~] spawn scp /root/ping.sh root@192.168.2.2:/tmp/ root@192.168.2.2's password: ping.sh 100% 34 13.8KB/s 00:00 # 使用刚刚写好的admin.exp运行刚才remote_copy.exp下发给2.2主机上的shell脚本ping.sh [root@lemon ~]# ./admin.exp 192.168.2.2 root 123123 "/tmp/ping.sh" spawn ssh root@192.168.2.2 /tmp/ping.sh root@192.168.2.2' s password: PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.020 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.037 ms 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.027 ms --- 127.0.0.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2005ms rtt min/avg/max/mdev = 0.020/0.028/0.037/0.007 ms
案例4:expect 变量的练习
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [root@lemon ~] set A [lindex $argv 0]set B [lindex $argv 1]set C [lindex $argv 2]set D lemonsend "\$A=$A \n" send "\$B=$B \n" send "\$C=$C \n" send "\$D=$D \n" send "\$argv=$argv \n" send "\$argc=$argc \n"
1 2 3 4 5 6 7 8 [root@lemon ~] [root@lemon ~] $A =a$B =b$C =c$D =lemon$argv =a b c d$argc =4
案例5:expect 结合 if 的练习,
注意: 括号的空格,严格要求
1 2 3 4 5 6 7 8 9 10 11 12 [root@lemon ~] if {$argc != 3} { send_user "usage: == $argc 不等于3!\n" exit } else { set FILE [lindex $argv 0]set HOST [lindex $argv 1]set DIR [lindex $argv 2]send_user "$FILE \t$HOST \t$DIR \n" }
1 2 3 4 5 6 7 [root@lemon ~] [root@lemon ~] usage: == 2 不等于3! [root@lemon ~] a b c
Linux 信号控制 shell案例 一、监控主机及联网状态 1. 监控目的
2. 监控方法
通过采用 ICMP协议的 ping命令对计算机进行 ping测试,通则表示主机为开启并联网,不通则代表主机宕机或断网。
3. 监控思路
4. 监控实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #!/bin/bash for ((i=1;i<4;i++));do if ping -c1 $1 &>/dev/null;then export ping_count"$i " =1 else export ping_count"$i " =0 fi sleep 0.3 done if [ $ping_count1 -eq $ping_count2 ] && [ $ping_count2 -eq $ping_count3 ]&&[ $ping_count1 -eq 0 ];then echo "$1 is down" else echo "$1 is up" fi unset ping_count1 unset ping_count2 unset ping_count3
二、监控主机服务状态 1. 监控目的
实时掌握线上机器服务状态,保证服务正常运行
2. 监控方法
采用telnet访问端口,通过返回数据分析判定结果
3. 监控实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #!/bin/bash port_status () {temp_file=`mktemp port_status.XXX` [ ! -x /usr/bin/telnet ]&&echo "telnet: not found command" && exit 1 ( telnet $1 $2 <<EOF quit EOF ) &>$temp_file if egrep "\^]" $temp_file &>/dev/null;then echo "$1 $2 is open" else echo "$1 $2 is close" fi rm -f $temp_file } port_status $1 $2
三、监控内存使用率 1. 监控目的 通过监控内存使用率判定机器内存资源消耗情况,及时处理并优化资源配比
2. 监控方法 2.1)监控命令
free
cat /proc/meminfo
等等……
2.2)监控指标
2.3)监控方法
通过上述命令对内存总量、使用量进行截取,取得内存使用率,并根据阈值进行判断。
3. 监控实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #!/bin/bash memory_use () {memory_used=`head -2 /proc/meminfo |awk 'NR==1{t=$2}NR==2{f=$2;print(t-f)*100/t"%"}' ` memory_cache=`head -5 /proc/meminfo |awk 'NR==1{t=$2}NR==5{c=$2;print c*100/t"%"}' ` memory_buffer=`head -4 /proc/meminfo |awk 'NR==1{t=$2}NR==4{b=$2;print b*100/t"%"}' ` echo -e "memory_used:$memory_used \tbuffer:$memory_buffer \tcached:$memory_cache " } memory_use
四、监控使用CPU或内存前十名进程
1. 监控目的
掌握系统进程对系统资源的使用情况,掌握机器的动态。
2. 监控方法 2.1)监控命令
2.2)监控方法
通过对任务管理器中的进程对内存或CPU的使用情况进行整合、排序得出结论
3. 监控实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #!/bin/bash memory () { temp_file=`mktemp memory.XXX` top -b -n 1 > $temp_file tail -n +8 $temp_file | awk '{array[$NF]+=$6}END{for (i in array) print array[i],i}' |sort -k 1 -n -r|head -10 rm -f $temp_file } cpu () { temp_file=`mktemp memory.XXX` top -b -n 1 > $temp_file tail -n +8 $temp_file | awk '{array[$NF]+=$9}END{for (i in array) print array[i],i}' |sort -k 1 -n -r|head -10 rm -f $temp_file } echo memorymemory echo cpu cpu
五、监控IO使用情况 1. 磁盘说明
磁盘在系统中负责存储和读取任务,磁盘的处理速度直接影响了计算机的速度,目前常用的磁盘有两种:固态和机械磁盘。
固态磁盘: 没有IO瓶颈,读写快,存储颗粒有擦写限制,价格高,容量小。
机械磁盘: 靠电机带动磁盘转动,通过磁头读取或存储数据,读写速度和磁盘转速有关,容量大、价格低,大量读写容易造成IO瓶颈。
2. 监控目的
随时掌握IO的使用情况,防止IO性能瓶颈
3. 监控指标
4. 监控命令
5. iostat语法 及 输出说明
用法:
iostat [ 选项 ] [ <时间间隔> [ <次数> ]]
常用选项:
-c:只显示系统CPU统计信息,即单独输出avg-cpu结果,不包括device结果
-d:单独输出Device结果,不包括cpu结果
-k/-m:输出结果以kB/mB为单位,而不是以扇区数为单位
-x:输出更详细的io设备统计信息
interval/count:每次输出间隔时间,count表示输出次数,不带count表示循环输出
输出含义:
avg-cpu: 总体cpu使用情况统计信息,对于多核cpu,这里为所有cpu的平均值。重点关注iowait值,表示CPU用于等待io请求的完成时间。
%user:CPU处在用户模式下的时间百分比。
%nice:CPU处在带NICE值的用户模式下的时间百分比。
%system:CPU处在系统模式下的时间百分比。
%iowait:CPU等待输入输出完成时间的百分比。
%steal:管理程序维护另一个虚拟处理器时,虚拟CPU的无意识等待时间百分比。
%idle:CPU空闲时间百分比。
Device: 各磁盘设备的IO统计信息。各列含义如下:
Device: 以sdX形式显示的设备名称
tps: 每秒进程下发的IO读、写请求数量
KB_read/s: 每秒从驱动器读入的数据量,单位为K。
KB_wrtn/s: 每秒从驱动器写入的数据量,单位为K。
KB_read: 读入数据总量,单位为K。
KB_wrtn: 写入数据总量,单位为K。
输出含义:
rrqm/s: 每秒对该设备的读请求被合并次数,文件系统会对读取同块(block)的请求进行合并
wrqm/s: 每秒对该设备的写请求被合并次数
r/s: 每秒完成的读次数
w/s: 每秒完成的写次数
rkB/s: 每秒读数据量(kB为单位)
wkB/s: 每秒写数据量(kB为单位)
avgrq-sz:平均每次IO操作的数据量(扇区数为单位)
avgqu-sz: 平均等待处理的IO请求队列长度
await: 平均每次IO请求等待时间(包括等待时间和处理时间,毫秒为单位)
svctm: 平均每次IO请求的处理时间(毫秒为单位)
%util: 采用周期内用于IO操作的时间比率,即IO队列非空的时间比率
重点关注参数:
1 2 3 4 5 6 7 8 9 10 11 12 1、iowait% 表示CPU等待IO时间占整个CPU周期的百分比,如果iowait值超过50%,或者明显大于%system、%user以及%idle,表示IO可能存在问题。 2、avgqu-sz 表示磁盘IO队列长度,即IO等待个数。 3、await 表示每次IO请求等待时间,包括等待时间和处理时间 4、svctm 表示每次IO请求处理的时间 5、%util 表示磁盘忙碌情况,一般该值超过80%表示该磁盘可能处于繁忙状态。 如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈。如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间;如果 await 远大于 svctm,说明I/O 队列太长,io响应太慢,则需要进行必要优化。如果avgqu-sz比较大,也表示有当量io在等待。 6、dm-0、dm-1、dm-2的主设备号是253(是linux内核留给本地使用的设备号),次设备号分别是0、1、2,这类设备在/dev/mapper中
6. 监控实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #!/bin/bash io () { device_num=`iostat -x |egrep "^sd[a-z]" |wc -l` iostat -x 1 3|egrep "^sd[a-z]" |tail -n +$((device_num+1 ))|awk '{io_long[$1]+=$9}END{for (i in io_long)print io_long[i],i}' } io
六、mysql binlog日志备份 1. 脚本思路 mysql binlog日志备份脚本 备份到备份服务器
#1) 确定binlog的位置及备份时间间隔 每天
#当前要备份的binlog是谁
#刷新binlog日志,生成新的binlog用于存储备份节点后的数据
#2)打包binlog日志 以年-月-日_binlog.tar.gz格式
#3)生成校验码 md5sum
#4)将校验码和压缩包存入到文件夹 文件夹命名 年-月-日 再次打包
#5)使用scp拷贝到备份机器
#6)备份机器解压收到的目录压缩包 通过校验码 教研binlog压缩包是否完整
#完整 完成备份 —–发邮件给管理员,明确备份成功
#不完整 报错——发邮件给管理员,要求手动备份
2. 代码如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 #!/bin/bash db_user='root' db_password='' log ='/var/log/mysql_backup.log' backup () {binlog_dir='/var/lib/mysql' current_binlog=`mysql -u $db_user -e "show master status" |egrep "binlog.[[:digit:]]*" |awk '{print $1}' ` date >> $log mysql -u $db_user -e "flush logs" tar czf `date +%F`_binlog.tar.gz $binlog_dir /$current_binlog &>>$log md5sum `date +%F`_binlog.tar.gz > "`date +%F`_md5sum.txt" [ ! -d `date +%F` ]&&mkdir `date +%F` mv `date +%F`_binlog.tar.gz `date +%F` mv `date +%F`_md5sum.txt `date +%F` tar czf `date +%F`.tar.gz `date +%F` &>>$log scp `date +%F`.tar.gz root@192.168.11.241:/opt/backup &>>$log if [ $? -ne 0 ];then echo "ERROR:scp `date +%F`.tar.gz fail" &>>$log exit 1 fi ssh root@192.168.11.241 "tar xf /opt/backup/`date +%F`.tar.gz -C /opt" ssh root@192.168.11.241 "cd /opt/`date +%F`;md5sum -c `date +%F`_md5sum.txt" &>>$log if [ $? -eq 0 ];then echo "success" &>>$log ssh root@192.168.11.241 "rm -rf /opt/`date +%F`" else echo "fail" &>>$log fi } backup
七、新建用户脚本
需求:新建 user01 - user20用户,要求密码是随机6位数 密码取值范围 a-zA-Z0-9,要求密码不能只是单一的数字或小写或大写字母
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #!/bin/bash adduser () {pw_txt=`mktemp pw.XXXXX` echo -e "account\t\tpassword" > user_add_result.txtfor i in `seq -s ' ' -w 1 20` do useradd user$i done cat /dev/urandom |strings -6|egrep "^[a-zA-Z0-9]{6}$" |head -n 20 > $pw_txt for i in `seq -s ' ' -w 1 20`;do pw=`head -n $i $pw_txt |tail -1` echo $pw |passwd --stdin user$i &>/dev/null echo -e "user$i \t\t$pw " >> user_add_result.txt done clear echo "用户创建成功,密码文件是:user_add_result.txt" cat user_add_result.txt rm -rf $pw_txt } adduser