shell编程

知识体系说明

工作、面试:

1配合定时任务执行备份 检查 2 3监控系统:自定义监控(只要能通过命令/脚本取出来的内容 就可以监控) 4 5服务管理脚本:sersync 编译安装的软件 systemctl start|stop|network network 6 7批量维护与管理 8 9

shell入坑指南

linux半边天

要求能力:

11. 熟练使用70-80个常见命令 22. 正则与三剑客 33. vim 快捷键 https://www.jianshu.com/p/c5e6724f4c3d 44. 掌握:根据需求 书写脚本能力 5 6

如何入坑:

书写建议

1把需求拆分 3步或更多 2 3分析每个步骤 给出每个步骤使用的命令 或语法 测试成功 4 5每个步骤ok, 书写合并脚本 6 7测试 8 9

学习建议

1尽量分析 系统脚本(想得多) 别人发出来的脚本 读懂。 2 3后面模仿 4 5

shell基础规则与习惯

基础规则- 执行脚本

1#方法1 sh ※※※※※※ 2[root@manager /server/scripts]# sh 2.3-1-exec.sh 3tar: 从成员名中删除开头的“/” 4#方法2 .或source 5[root@manager /server/scripts]# . 2.3-1-exec.sh 6tar: 从成员名中删除开头的“/” 7#方法3 输入重定向方法 8[root@manager /server/scripts]# sh <2.3-1-exec.sh 9tar: 从成员名中删除开头的“/” 10[root@manager /server/scripts]# ll /tmp/etc.tar.gz 11-rw-r--r-- 1 root root 10246600 18 10:51 12/tmp/etc.tar.gz 13#linux 支持 < 很多 tr xargs 三剑客 14#方法4 绝对路径方法 15[root@manager /server/scripts]# ll 16/server/scripts/2.3-1-exec.sh 17-rwxr-xr-x 1 root root 31 18 10:50 18/server/scripts/2.3-1-exec.sh 19[root@manager /server/scripts]# /server/scripts/2.3-1- 20exec.sh 21tar: 从成员名中删除开头的“/” 22 23

sh 执行各种命令 必备 ./source 在脚本中调用使用其他文件方法在脚本中实现nginx include功能 , ./etc/init.d/fuctions 服务、命令检查脚本 sh < 几乎不会用 绝对路径 系统脚本 系统使用的脚本 需要+x权限

1#./source 了解 2[root@manager /server/scripts]# . 3/etc/init.d/functions 4[root@manager /server/scripts]# action "crond is 5running" /bin/true 6crond is running 7 [ 确定 ] 8[root@manager /server/scripts]# action "crond is not 9running" /bin/false 10crond is not running 11 [失败] 12 13

书写shell脚本的习惯

书写脚本 加上 命令解释器 #!/bin/bash 脚本默认使用的命令解释器
#! 幻数

1[root@manager /server/scripts]# head -1 /bin/yum 2#!/usr/bin/python 3[root@manager /server/scripts]# file 2.3-2-checkweb.sh 4 3-2-check-web.sh: UTF-8 Unicode text 5[root@manager /server/scripts]# 6[root@manager /server/scripts]# file 2.3-2-checkweb.sh 72.3-2-check-web.sh: Bourne-Again shell script, UTF-8 8Unicode text executable 9 10

shell变量

普通变量(局部变量)

变量:

1存放我们经常使用的内容(shell脚本中) 2本质:内存中空间 3 4

空间的位置 变量名
空间的内容 变量值

变量的命名规则

1不能以数字开头 最好也不要包含特殊符号 ! - 最好用_ 下划线 2 3命名规律: 推荐 多个单词通过下划线连接 (表名变量的作用) bingbing_age=16 4 5驼峰写法: 多个单词从第2个单词开始 首字母大写 lidaoAge=99 numberOfPeople=61 6 7

变量赋值注意事项

1[root@manager /server/scripts]# oldbing=666 2[root@manager /server/scripts]# echo $oldbing 3666 4[root@manager /server/scripts]# oldbing=爱生活 爱冰冰 5-bash: 爱冰冰: 未找到命令 6[root@manager /server/scripts]# oldbing="爱生活 爱冰冰" 7[root@manager /server/scripts]# echo $oldbing 8爱生活 爱冰冰 9 10

单引号 所见即所得 单引号里面内容 原封不动输出 双引号 与单引号类似 解析特殊符号 `` $() ! 不加引号 与双引号类似 支持通配符 * {} 反引号 优先执行命令

example:

1[root@manager ~]# echo '$PATH $(hostname) `whoami` 2{1..5}' 3$PATH $(hostname) `whoami` {1..5} 4[root@manager ~]# echo "$PATH $(hostname) `whoami` 5{1..5}" 6/sbin:/usr/sbin:/bin:/usr/bin manager root {1..5} 7[root@manager ~]# echo $PATH $(hostname) `whoami` 8{1..5} 9/sbin:/usr/sbin:/bin:/usr/bin manager root 1 2 3 4 5 10 11

环境变量(全局变量)

特点

11.Linux系统创建 22.大写 33.Linux大部分地方都可以使用 4 5

查看所有环境变量

1env 2export 3declare 4 5

在这里插入图片描述

创建环境变量

1[root@manager ~]# oldboy=666 2[root@manager ~]# echo $oldboy 3666 4[root@manager ~]# env |grep oldboy 5[root@manager ~]# #export 变量 变量成为环境变量 6[root@manager ~]# export oldboy=666 7[root@manager ~]# env |grep oldboy 8oldboy=666 9 10

环境变量相关的文件和目录

/etc/profile 别名 环境变量

/etc/bashrc 别名

~/.bashrc 当前用户的别名

~/.bash_profile 当前用户环境变量

/etc/profile.d/ 目录里面的内容 .sh结尾的 会在用户登录后运行 存放shell跳板机脚本存放用户行为记录脚本

在这里插入图片描述

shell特殊变量

表示位置的特殊变量

$数字 $1,$1… 脚本的第1个 第2个参数 $0 echo "Usage: $0{start|restart|stop}" 脚本的文件名 $#

脚本参数的个数 脚本一共有几个参数 $*

取出脚本所有的参数 $@

取出脚本所有的参数

1. $数字

1#基础用法 2[root@manager ~]# cat /server/scripts/2.5-1-arg.sh 3#!/bin/bash 4echo $1 $2 5[root@manager ~]# sh /server/scripts/2.5-1-arg.sh a b 6a b 7[root@manager ~]# 8#实际案例 9/etc/init.d/network start === $1=start 10 11
1#进阶: 脚本有多个参数 2[root@manager ~]# echo echo \${1..12} 3echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 4[root@manager ~]# echo echo \${1..12} >> 5/server/scripts/2.5-1-arg.sh 6[root@manager ~]# cat /server/scripts/2.5-1-arg.sh 7#!/bin/bash 8echo $1 $2 9echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 10[root@manager ~]# sh /server/scripts/2.5-1-arg.sh 11{1..12} 121 2 131 2 3 4 5 6 7 8 9 10 11 12 14#脚本参数超过9个 脚本参数需要使用 ${10} ${11} ※※※※※※ 15[root@manager ~]# cat /server/scripts/2.5-1-arg.sh 16#!/bin/bash 17echo ${1} ${2} 18echo ${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} 19${10} ${11} ${12} 20 21
1[root@manager ~]# sh /server/scripts/2.5-1-arg.sh 2{a..z} 3a b 4a b c d e f g h i j k l 5#认识 ${} $ 一致 取出变量的内容 6[root@manager ~]# age=18 7[root@manager ~]# echo $age 818 9[root@manager ~]# echo $agesui 10[root@manager ~]# echo ${age}sui 1118sui 12[root@manager ~]# #金庸新作 13[root@manager ~]# #${金庸}新作 14 15

小结

1$数字 脚本传参 命令行内容 传递到脚本的内部 /etc/init.d/network start 2#脚本参数超过9个 脚本参数需要使用 ${10} ${11} 3$与${} 4 5

2. $0
脚本的名字

1#简单案例 2[root@manager ~]# cd /server/scripts/ 3[root@manager /server/scripts]# sh 2.5-1-arg.sh 42.5-1-arg.sh 5[root@manager /server/scripts]# sh 6/server/scripts/../../server/scripts/2.5-1-arg.sh 7/server/scripts/../../server/scripts/2.5-1-arg.sh 8 9
1#实际应用 2#书写脚本 如果脚本执行出错 错误提示会使用 $0 3##usage 使用帮助 使用说明 4[root@manager /server/scripts]# /etc/init.d/network 5oldboy 6Usage: /etc/init.d/network {start|stop|status|restart|force-reload} 7 $0 8[root@manager /server/scripts]# sh 2.5-1-arg.sh 92.5-1-arg.sh 10Usage: 2.5-1-arg.sh {start|stop|restart} 11[root@manager /server/scripts]# cat 2.5-1-arg.sh 12#!/bin/bash 13echo ${1} ${2} 14echo ${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} 15${10} ${11} ${12} 16echo $0 17echo "Usage: $0 {start|stop|restart}" 18 19

小结

1$0 使用在 脚本遇到错误的时候 错误提示 2 3

3. $# 脚本参数的个数

1#基础用法 2[root@manager /server/scripts]# cat 2.5-1-arg.sh 3#!/bin/bash 4#echo ${1} ${2} 5#echo ${1} ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} 6${10} ${11} ${12} 7#echo $0 8#echo "Usage: $0 {start|stop|restart}" 9echo $1 $2 $# 10 11
1[root@manager /server/scripts]# sh 2.5-1-arg.sh 20 3[root@manager /server/scripts]# sh 2.5-1-arg.sh 4oldboy oldbing lidao 5oldboy oldbing 3 6#实际应用 7##一般与 判断一起使用 如果脚本参数个数=0 ? 提示报错信息 8/etc/init.d/network 9案例 : /etc/init.d/functions 10452 if [ "$#" = 0 ] ; then 11453 echo "Usage: status [-p pidfile] 12{program}" 13454 return 1 14455 fi 15 16

小结

1$# 脚本参数的个数 2一般配合判断 判断脚本参数个数如果是0 提示报错信息 3 4

4. $ 与 $@*

$* 取出脚本所有参数 $1 $2 $3 …$999 一般配合循环 加上双引号的时候区别 : 表示1个整体 1个参数 $@ 取出脚本所有参数 $1 $2 $3 …$999 一般配合循环 加上双引号的时候区别 : 每个参数独立

$* 和 $@区别

1#set 可以设置命令行参数 2[root@manager ~]# set oldboy alex 3[root@manager ~]# echo $1 4oldboy 5[root@manager ~]# echo $2 6alex 7# 通过set 测试 $* $@ 区别 8[root@manager ~]# set oldboy oldbing oldlidao 9oldguo 10[root@manager ~]# for n in "$*"; do echo $n; done 11oldboy oldbing oldlidao oldguo 12[root@manager ~]# for n in $*; do echo $n; done 13oldboy 14oldbing 15oldlidao 16oldguo 17[root@manager ~]# for n in $@ ; do echo $n; done 18oldboy 19oldbing 20oldlidao 21oldguo 22[root@manager ~]# for n in "$@" ; do echo $n; done 23oldboy 24oldbing 25oldlidao 26oldguo 27# 了解: $@ "$@" 区别 28[root@manager ~]# set "I am" oldboy linux teacher 29[root@manager ~]# echo $# 304 31[root@manager ~]# for n in $@ ; do echo $n; done 32I 33am 34oldboy 35linux 36teacher 37[root@manager ~]# for n in "$@" ; do echo $n; done 38I am 39oldboy 40linux 41teacher 42 43

小结

1$* $@ 取出脚本所有参数 一般配合for循环使用 2$* $@ 区别 3 4

5. 位置参数小结

$数字 脚本的第1个 第2个参数 实现脚本传参/etc/init.d/network start服务管理脚本 $0 脚本的名称 脚本执行报错 错误提示中 使用echo "Usage: $0 start $# 脚本参数的个数 脚本一共有几个参数 一般与判断一起使用 检查脚本参数个数是否为0 $* 取出脚本所有的参数 一般与for循环一起使用 ; 与shell数组一起使用 $@ 取出脚本所有的参数 一般与for循环一起使用 ; 与shell数组一起使用

表示状态变量

在这里插入图片描述
1. $?

1# $? 上1个命令或脚本 返回值 2#简单含义 与 应用 3##0 表示成功 4##非0 表示故障 失败 5root@manager ~]# ls 6ansible_playbook ansible_tasks 7student.txt 8ansible-project1 ansible_variables 9yj.sh 10ansible_role ansible_variableszip.zip 11ansible_role_2019-12-23.zip ssh-key.sh 12[root@manager ~]# echo $? 130 14#应用 15##与判断 结合 检查命令 脚本执行是否成功 16#ping wget 。。。。 17[ "$?" -eq 0 ] #equal 等于 判断返回值如果是0 则xxx 18 19

小结

1$? 配合判断 检查命令 脚本 执行是否成功 2 3

2. $$

1# $$ 当前脚本的pid 进程id 2###pid文件 3[root@manager ~]# systemctl start nginx 4[root@manager ~]# 5[root@manager ~]# ps -ef |grep nginx 6root 8504 1 0 11:33 ? 00:00:00 7nginx: master process /usr/sbin/nginx 8nginx 8505 8504 0 11:33 ? 00:00:00 9nginx: worker process 10root 8507 7560 0 11:33 pts/0 00:00:00 grep 11--color=auto nginx 12[root@manager ~]# #kill 8504 13[root@manager ~]# cat /run/nginx.pid 148504 15[root@manager ~]# kill `cat /run/nginx.pid` 16[root@manager ~]# ps -ef |grep nginx 17root 8519 7560 0 11:35 pts/0 00:00:00 grep 18--color=auto nginx 19### 手动创建pid文件 20[root@manager ~]# cat /server/scripts/2.5-3-pid.sh 21 22#!/bin/bash 23#author:oldboy lidao 24echo $$ 25sleep 9999 26[root@manager ~]# 27[root@manager ~]# sh /server/scripts/2.5-3-pid.sh 288578 29[root@manager ~]# ps -ef |grep 8578 30root 8578 7560 0 11:36 pts/0 00:00:00 sh 31/server/scripts/2.5-3-pid.sh 32root 8579 8578 0 11:36 pts/0 00:00:00 33sleep 9999 34root 8581 7493 0 11:37 pts/2 00:00:00 grep 35--color=auto 8578 36[root@manager ~]# 37[root@manager ~]# echo oldboy 38oldboy 39[root@manager ~]# echo oldboy |tee oldboy.txt 40oldboy 41[root@manager ~]# cat oldboy.txt 42oldboy 43[root@manager ~]# #tee 多向输出 前面的信息输出屏幕 同时写入 44到文件 45` 46[root@manager ~]# cat /server/scripts/2.5-3-pid.sh 47#!/bin/bash 48#author:oldboy lidao 49echo $$ |tee /run/lidao.pid 50sleep 9999 51[root@manager ~]# sh /server/scripts/2.5-3-pid.sh 528589 53[root@manager ~]# cat /run/lidao.pid 548589 55 56

小结

1$$ 在脚本中获取 脚本的pid 创建pid文件 2 3

3. 表示状态环境变量小结
在这里插入图片描述

变量子串

对变量的内容 进行 替换 删除

基础

${parameter} 取变量内容 ${#parameter} 统计变量的长度(多少个字符) 截取 类似cut 命令

${parameter:1}

${parameter:1:2}

删除

${parameter#word} 删除 ${parameter##word}

${parameter%word}

${parameter%%word}

替换

${parameter/找谁/替换为什么}

${parameter//找谁/替换为什么}

1. ${#parameter}

1#基础用法 2[root@manager ~]# oldboy=oldbing 3[root@manager ~]# echo ${oldboy} 4oldbing 5[root@manager ~]# echo ${#oldboy} 67 7 8#企业面试题 9##4.3-1面试题: I am oldboy linux,welcome to our 10training. 显示这串字符中 单词字符数大于6的单词 11##分析: 12###1.通过for循环 取出每个单词 13###2.判断 字符数 > 6 ? 14###1)大于6显示 15###2)不大于 继续 读取下1个单词 16[root@manager ~]# vim /server/scripts/2.5-3-word.sh 17#!/bin/bash 18#author oldboy lidao 19str="I am oldboy linux,welcome to our training. " 20for n in $str 21do 22 if [ ${#n} -gt 6 ] #great than 23 then 24 echo ${#n} $n 25 fi 26done 27 28[root@yida scripts]# cat test_word.sh 29#!/bin/bash 30str=$(echo 'I am oldboy linux,welcome to our training.' |sed 's#[,.]# #g') 31for n in $str 32do 33 if [ ${#n} -gt 6 ] 34 then 35 echo ${#n} $n 36 fi 37done 38[root@yida scripts]# sh test_word.sh 397 welcome 408 training 41 42[root@manager ~]# echo I am oldboy linux,welcome to our 43training.| 44> awk -vRS="[ ,.]" 'length()>6' 45welcome 46training 47 48

2. 变量截取

1[root@manager ~]# oldboy=oldboyedu.com 2[root@manager ~]# #echo ${oldboy:起始点:一共取多少个字符} 3[root@manager ~]# 4[root@manager ~]# echo ${oldboy:4:3} 5oye 6#截取功能字符是从0开始 7[root@manager ~]# echo ${oldboy:3:3} 8boy 9[root@manager ~]# echo ${oldboy:3} 10boyedu.com 11 12

在这里插入图片描述
3. 删除

${parameter##word}

删除匹配前缀(去掉左边最长匹配模式)

${parameter%word} % 删除匹配后缀( 去掉右边,最短匹配模式) ${parameter%%word} %% 删除匹配后缀(去掉右边,最长匹配模式)

1#简单使用 2[root@manager ~]# test='I am oldboy teacher' 3[root@manager ~]# echo ${test#I} 4am oldboy teacher 5[root@manager ~]# echo ${test#o} 6I am oldboy teacher 7[root@manager ~]# echo ${test#I am o} 8ldboy teacher 9[root@manager ~]# echo ${test#*o} 10ldboy teacher 11[root@manager ~]# echo ${test##*o} 12y teacher 13 14[root@manager ~]# test='I am oldboy teacher' 15[root@manager ~]# echo ${test%r} 16I am oldboy teache 17[root@manager ~]# echo ${test%er} 18I am oldboy teach 19[root@manager ~]# echo ${test%o*} 20I am oldb 21[root@manager ~]# echo ${test%%o*} 22I am 23#应用 24##简单 sed 比较麻烦 使用 变量子串里面删除功能 25[root@manager ~]# net='/etc/sysconfig/networkscripts/ifcfg-eth0' 26[root@manager ~]# 27[root@manager ~]# echo ${net##*/} 28ifcfg-eth0 29[root@manager ~]# echo ${net%%/*} 30[root@manager ~]# echo ${net%/*} 31/etc/sysconfig/network-scripts 32[root@manager ~]# 33[root@manager ~]# dirname /etc/sysconfig/networkscripts/ifcfg-eth0 34/etc/sysconfig/network-scripts 35[root@manager ~]# basename /etc/sysconfig/networkscripts/ifcfg-eth0 36ifcfg-eth0 37#使用linux命令 效率 比 变量子串 低 38root@manager ~]# time for n in {1..10000} ;do echo 39${#n} &>/dev/null ; done 40real 0m0.154s 41user 0m0.097s 42sys 0m0.056s 43[root@manager ~]# time for n in {1..10000} ;do 44echo ${n}|wc -L &>/dev/null ; done 45real 0m20.292s 46user 0m8.485s 47sys 0m11.692s 48 49

小结:

1变量子串删除部分 主要用来在脚本中删除路径 里面的名字 或路径部分 2 3

4. 替换

${parameter/找谁/替换为什么} 只替换第1个 ${parameter//找谁/替换为什么} 全局替换

1[root@manager ~]# test='I am oldboy teacher' 2[root@manager ~]# echo ${test/[a-z]/oldboy} 3I oldboym oldboy teacher 4[root@manager ~]# echo ${test//[a-z]/oldboy} 5I oldboyoldboy oldboyoldboyoldboyoldboyoldboyoldboy 6oldboyoldboyoldboyoldboyoldboyoldboyoldboy 7[root@manager ~]# 8[root@manager ~]# test='I am oldboy teacher' 9[root@manager ~]# echo ${test//oldboy/} 10I am teacher 11[root@manager ~]# echo ${test/oldboy/} #把oldboy替换为空 12即删除 13I am teacher 14 15

5. 变量子串小结

基础

${parameter} 取变量内容 ${#parameter} 统计变量的长度 (多少个字符) 截取(切片) 类似cut 命令 用法:cut -c ${parameter:1}

${parameter:1:2}

删除 处理文件名路径 ${parameter#word} 删除变量中开头的word 最小匹配 ${parameter##word} 删除变量中开头的word 最长匹配 ${parameter%word} 删除变量中结尾的word 最小匹配 ${parameter%%word} 删除变量中结尾的word 最长匹配 替换

${parameter/找谁/替换为什么} 最小匹配 ${parameter//找谁/替换为什么} 最大匹配

#通配符

1* 2{} 3[] 4[^] 5? 6 7

特殊变量

功能: 实现给变量设置默认值。

${parameter:-word} 如果parameter没有被赋值或者其值为空,那么就以word作为其值 ${parameter:=word} 如果parameter没有被赋值或者其值为空,那么就以word作为其值,并且将word赋值给parameter ${parameter:?word} 如果parameter没有被赋值或者其值为空,那么就把word作为错误输出.否则显示parameter内容 ${parameter:+word} 如果parameter没有被赋值或者其值为空,就什么都不做.否则用word替换变量内容

1[root@manager ~]# echo $oldbing 2[root@manager ~]# echo ${oldbing:-14} 314 4[root@manager ~]# oldbing=13 5[root@manager ~]# echo ${oldbing:-14} 613 7[root@manager ~]# echo ${lidao:-14} 814 9[root@manager ~]# echo $lidao 10[root@manager ~]# echo ${lidao:=14} 1114 12[root@manager ~]# echo $lidao 1314 14[root@manager ~]# echo ${lidao:?14} 15-bash: lidao: 14 16root@manager ~]# lidao=99 17[root@manager ~]# echo ${lidao:+14} 1814 19[root@manager ~]# echo ${lidaov2:+14} 20 21

6. 特殊变量总结

1状态 2 3位置变量 man bash Special Parameters 特殊参数 4变量子串 man bash parameter expansion 变量扩展 5位置变量 6状态变量 7变量子串 8其他变量 9 10

特殊变量

状态 $? $$ $_ $! 变量子串 基础${oldboy} ${#oldboy}

截取${parameter:1} ${parameter:1:2}

删除${oldboy#word} ${oldboy%word}

替换${oldboy/谁/替换为什么} ${oldboy//谁/替换为什么} 变量扩展 给变量设置默认值:${oldboy:-word}${oldboy:=word}

运算

运算符

在这里插入图片描述
注:

1i=i+1 i++ 计数统计次数 2sum=sum+xxx 3sum+=xxxx 累加求和 4 5
1[root@manager ~]# #生成指定范围的随机数 2[root@manager ~]## echo $RANDOM%数字 |bc 3 4

Linux计算方法

bc

(())

let

awk

expr

$[ ]

1. bc basic calc

1#基础用法 2[root@manager ~]# echo 1+2 |bc 33 4[root@manager ~]# echo 10/3 |bc 53 6[root@manager ~]# echo 1/3 |bc 70 8#bc显示小数 9[root@manager ~]# echo 1/3 |bc -l 10.33333333333333333333 11[root@manager ~]# echo 10/3 |bc -l 123.33333333333333333333 13[root@manager ~]# 14#指定位数的小数 了解 15[root@manager ~]# echo 'scale=2;10/3' |bc -l 163.33 17 18

2. (())

1[root@manager ~]# ((1+1)) 2[root@manager ~]# ((a=1+1)) 3[root@manager ~]# echo $a 42 5[root@manager ~]# ((i=i+1)) 6[root@manager ~]# echo $i 71 8[root@manager ~]# ((i=i+1)) 9[root@manager ~]# echo $i 102 11[root@manager ~]# ((i=i+1)) 12[root@manager ~]# echo $i 133 14[root@manager ~]# echo $((1+1)) 152 16 17

3. let

1[root@manager ~]# unset i 2[root@manager ~]# let i++ 3[root@manager ~]# echo $i 41 5[root@manager ~]# let i++ 6[root@manager ~]# echo $i 72 8[root@manager ~]# let a=1+1 9[root@manager ~]# echo $a 102 11 12

4. awk

1[root@manager ~]# awk 'BEGIN{print 1/3}' 20.333333 3[root@manager ~]# awk 'BEGIN{print 1/3,2^10,2^16}' 40.333333 1024 65536 5 6

5. expr

1#基本及小坑 2#使用 * 乘法 需要转义 3[root@manager /opt]# expr 10 * 10 4100 5[root@manager /opt]# expr 10 \* 10 6100 7#隐藏功能 判断参数、变量是否为数字 8[root@manager /opt]# expr 10 + 10 920 10[root@manager /opt]# echo $? 110 12[root@manager /opt]# expr a + 10 13expr: non-integer argument 14[root@manager /opt]# echo $? 152 16#判断参数、变量是否为数字 17[root@manager /opt]# expr 10 + b 18expr: non-integer argument 19[root@manager /opt]# echo $? 202 21[root@manager /opt]# expr 10 + 10b 22expr: non-integer argument 23[root@manager /opt]# echo $? 242 25# 使用expr判断参数是否为数字 坑 26[root@manager /opt]# x=0 27[root@manager /opt]# y=0 28[root@manager /opt]# expr $x + $y 290 30[root@manager /opt]# echo $? 311 32[root@manager /opt]# expr $x + $y + 1 331 34[root@manager /opt]# echo $? 350 36 37

6. $[ ]

1[root@manager /opt]# echo $[1+1] 22 3[root@manager /opt]# echo $[1/3] 40 5 6

7. 运算方法小结

bc 计算 显示小数 (()) 计算整数 里面变量直接使用 不需要加上$ ((运算公式)) 输出到屏幕 echo $(()) let 计算整数 里面变量直接使用 不需要加上$ 后面接上 公式 awk 计算 显示小数 过滤 expr 计算整数 判断参数或变量是否为数字 $[ ] 计算整数

shell条件语句 条件表达式

条件表达式----通过 符号 判断 文件 变量 比较大小放在 if判断 或 循环中

基础格式

test <条件>

[ <条件> ] 一般情况通用 [[ <条件> ]] [ ] 升级版 支持正则表达式 (( <条件> ))

判断文件相关

-f file 判断文件是否存在 存在则为真 -d directory 判断目录是否存在 存在则为真 -e exist 判断这个是否存在(文件 目录 软连接) -x execute 判断是否有x权限 -s size 判断文件是否为空 (大小是否为0) 如果大于0 则为真 -r read 是否有读 -w write 是否有写 -L Symlink (symbolic link或soft link) 判断文件是否存在并且 是否为软连接 f1 -nt f2 file1 newer than file2 f1 -ot f2 file2 older than file2

在这里插入图片描述

1[root@manager /opt]# [ -f /etc/hosts ] 2[root@manager /opt]# [ -f /etc/hos ] 3[root@manager /opt]# echo $? 41 5[root@manager /opt]# [ -f /etc/hosts ] && echo 真 存在 6|| echo 假 不存在 7真 存在 8[root@manager /opt]# [ -f /etc/host ] && echo 真 存在 9|| echo 假 不存在 10-bash: cho: command not found 11假 不存在 12[root@manager ~]# [ -f /etc/hosts ] && echo 真 存在 13|| echo 假 不存在 14真 存在 15[root@manager ~]# [ -d /etc/hosts ] && echo 真 存在 16|| echo 假 不存在 17假 不存在 18[root@manager ~]# [ -d /etc/init.d ] && echo 真 存在 19|| echo 假 不存在 20真 存在 21[root@manager ~]# [ -x /sbin/ip ] && echo 真 存在 || 22echo 假 不存在 23真 存在 24# 25[ -x /sbin/ip ] || exit 1 26#-s 27[root@manager ~]# > oldboy.txt 28[root@manager ~]# [ -s oldboy.txt ] && echo 真 || 29echo3031[root@manager ~]# echo 1 >oldboy.txt 32[root@manager ~]# [ -s oldboy.txt ] && echo 真 || 33echo3435 36

字符串比较

"串1" = "串2" 判断两个字符串 是否相等 如果相等则真 "串1" != "串2" 判断两个字符串 是否相等 如果不相等则真 -z zero 如果字符串、变量 是空的 则为真 -n not zero 如果字符串、变量 不是空的 则为真

1# 判断字符串是否相等 2[root@manager ~]# [ "oldboy" = "oldboy" ] && echo 等于 3||echo 不等于 4等于 5[root@manager ~]# [ "oldboy" != "oldboy" ] && echo 不等 6||echo 等于 7等于 8[root@manager ~]# 9# 小坑 10[root@manager ~]# [ "oldboy" = "oldboy" ] && echo 等于 11||echo 不等于 12等于 13[root@manager ~]# [ "oldboy" != "oldboy" ] && echo 不等 14||echo 等于 15等于 16[root@manager ~]# 17[root@manager ~]# echo $oldboy 18[root@manager ~]# [ -z $oldboy ] && echo 空 || echo 不 192021[root@manager ~]# [ -n $oldboy ] && echo 不空 || echo 2223不空 24#在使用字符串 变量比较时候要使用双引号 把字符串或变量引起来 25[root@manager ~]# 26[root@manager ~]# [ -n "$oldboy" ] && echo 不空 || echo 272829#实际案例 30[ "${NETWORKING}" = "no" ] && exit 6 31if [ -z "$DEVICE" ] ; then DEVICE="$i"; fi 32 33

小结:

1给字符串、变量 加上双引号 2 3一般配合if 4 5

数字比较

在这里插入图片描述

1[root@manager ~]# [ 1 -eq 1 ] && echo 真 ||echo 假 23[root@manager ~]# [ 99 -gt 1 ] && echo 真 ||echo 假 45[root@manager ~]# [ 1 -gt -10 ] && echo 真 ||echo 假 67[root@manager ~]# [ 1.1 -gt -10 ] && echo 真 ||echo 假 8-bash: [: 1.1: 期待整数表达式 910[root@manager ~]# [ 1 -gt -10 ] && echo 真 ||echo 假 1112[root@manager ~]# test 1 -gt -10 && echo 真 ||echo 假 1314[root@manager ~]# 15[root@manager ~]# 16[root@manager ~]# 17[root@manager ~]# 18[root@manager ~]# [[ 2 >= 10 ]] && echo 真 ||echo 假 19-bash: 条件表达式中有语法错误 20-bash: `10' 附近有语法错误 21[root@manager ~]# [[ 2 > 10 ]] && echo 真 ||echo 假 2223[root@manager ~]# (( 2 >= 10 )) && echo 真 ||echo 假 2425[root@manager ~]# (( 2 <= 10 )) && echo 真 ||echo 假 2627 28

条件表达式的使用格式

1[ 条件 ] && { 2命令1 3命令2 4命令3 5} 6 7[ 条件 ] || { 8命令1 9命令2 10命令3 11} 12 13

#脚本输入2个参数 比较两个是否相等 相等 显示相等 不相等显示不相

#脚本输入2个参数 比较两个数字大小 大于 显示 > 小于 <
等于 =
#脚本输入2个参数 比较两个数字大小 大于 显示 > 小于 <
等于 = 输入必须是数字
#脚本输入2个参数 比较两个是否相等 相等 显示相等 不相等显示不相

#脚本输入2个参数 比较两个是否相等 相等 显示相等 不相等显示不相

##分析:
###通过命令行传递 2个参数 给脚本
####判断参数个数如果不是2
###脚本对比两个参数 一致
####如果相等
####如果不等

在这里插入图片描述

1[root@manager /server/scripts]# sh 2.5-4-comp.sh 2Must have two args 3[root@manager /server/scripts]# sh 2.5-4-comp.sh 10 42b 5Usage: Must have two number 6[root@manager /server/scripts]# sh 2.5-4-comp.sh 10 720 810 -lt 20 9[root@manager /server/scripts]# sh 2.5-4-comp.sh 20 1010 1120 -gt 10 12[root@manager /server/scripts]# sh 2.5-4-comp.sh 10 1310 1410 -eq 10 15 16

在这里插入图片描述
在这里插入图片描述

逻辑测试符号

-a and并且 && -o or或者 || ! !取反 !

1[root@manager /server/scripts]# [ -d /etc -a -f 2/etc/hosts ] && echo 1|| echo 0314[root@manager /server/scripts]# [ -d /et -a -f 5/etc/hosts ] && echo 1|| echo 0607[root@manager /server/scripts]# [ -d /et -o -f 8/etc/hosts ] && echo 1|| echo 09110[root@manager /server/scripts]# 11[root@manager /server/scripts]# [ ! -d /et ] && 12echo 1|| echo 013114#表示大于等于10并且小于等于100的数字 15[root@manager /server/scripts]# num=4 16[root@manager /server/scripts]# [ $num -ge 10 -a $num 17-le 100 ] && echo 1 || echo 0 180 19[root@manager /server/scripts]# num=50 20[root@manager /server/scripts]# [ $num -ge 10 -a $num 21-le 100 ] && echo 1 || echo 0 221 23[root@manager /server/scripts]# test $num -ge 10 -a 24$num -le 100 && echo 1 || echo 0 251 26[root@manager /server/scripts]# 27[root@manager /server/scripts]# [[ $num -ge 10 && $num 28-le 100 ]] && echo 1 || echo 0 291 30[root@manager /server/scripts]# # 10 ~ 100 31[root@manager /server/scripts]# # <10 >100 32[root@manager /server/scripts]# 33[root@manager /server/scripts]# num=1 34[root@manager /server/scripts]# [ ! $num -ge 10 -o ! 35$num -le 100 ] && echo 1 || echo 0 361 37[root@manager /server/scripts]# [ $num -lt 10 -o 38$num -gt 100 ] && echo 1 || echo 0 391 40 41

正则表达式

[[ “oldboy123” =~ ^[0-9]+$ ]]

1[root@manager ~]# [[ "12345" =~ [0-9] ]] && echo 1 2|| echo 0 31 4[root@manager ~]# [[ "oldboy" =~ [0-9] ]] && echo 1 5|| echo 0 60 7[root@manager ~]# [[ "oldboy123" =~ [0-9] ]] && echo 81 || echo 0 91 10#精确匹配数字 11[root@manager ~]# [[ "oldboy123" =~ ^[0-9]+$ ]] && 12echo 1 || echo 0 130 14 15
1命令行传入1个字符或数字,数字等于1则显示1,如果等于2则显示2,如果 2既不等于1也不等于2,就显示输入不对,然后退出程序 3从命令行传入1个参数 4是否为1或2,否则退出 5如果1 显示1 6如果2 显示2 7 8
1[root@manager ~]# cat /server/scripts/2.5-5-input.sh 2#!/bin/bash 3#author: oldboy 4str=$1 5#[ "$str" -ne 1 -o "$str" -ne 2 ] 6[[ ! "$str" =~ ^[12]$ ]] && { 7echo input error 8exit 1 9} 10[ "$str" -eq 1 ] && echo 1 11[ "$str" -eq 2 ] && echo 2 12[root@manager ~]# sh /server/scripts/2.5-5-input.sh 13input error 14[root@manager ~]# sh /server/scripts/2.5-5-input.sh 3 15input error 16[root@manager ~]# sh /server/scripts/2.5-5-input.sh 1712 18input error 19[root@manager ~]# sh /server/scripts/2.5-5-input.sh 1 201 21[root@manager ~]# sh /server/scripts/2.5-5-input.sh 2 222 23[root@manager ~]# sh /server/scripts/2.5-5-input.sh a 24input error 25[root@manager ~]# [[ "oldboy123" =~ [12] ]] && echo 261 || echo 0 271 28[root@manager ~]# [[ "1" =~ [12] ]] && echo 1 || 29echo 0 301 31[root@manager ~]# [[ "2" =~ [12] ]] && echo 1 || 32echo 0 331 34[root@manager ~]# [[ "12" =~ [12] ]] && echo 1 || 35echo 0 361 37[root@manager ~]# [[ "12" =~ ^[12]$ ]] && echo 1 || 38echo 0 39[root@manager ~]# [[ "12" =~ ^[12]$ ]] && echo 1 || 40echo 0 410 42[root@manager ~]# [[ "1111" =~ ^[12]$ ]] && echo 1 43|| echo 0 440 45[root@manager ~]# [[ "1" =~ ^[12]$ ]] && echo 1 || 46echo 0 471 48[root@manager ~]# [[ "2" =~ ^[12]$ ]] && echo 1 || 49echo 0 501 51 52

条件表达式总结

符号 test [ ] [[ ]] (()) 文件 -d -f -x -s -r -w -L -h 字符串 使用双引号 = != -z -n 数字 -eq -ne -gt -ge -le -lt 逻辑 -a -o ! 正则 [[ 变量/字符 =~ 正则 ]]

在这里插入图片描述

变量与后台运行

变量赋值方式

直接赋值 oldboy=123 ; name=

1hostname
参数传递(脚本传参) oldboy=$1 sh oldboy.sh 10 通过read赋值 交互式赋值 read -p ‘input password:’ pass

1#read交互式 复制 2[root@manager ~]# read -p 'input password:' pass 3input password:******* 4[root@manager ~]# read -p 'input password:' pass 5input password:oldboy 6[root@manager ~]# echo $pass 7oldboy 8#read交互式赋值多个变量 9[root@manager ~]# read -p 'input num1 num2:' n1 n2 10input num1 num2:10 20 11[root@manager ~]# echo $n1 1210 13[root@manager ~]# echo $n2 1420 15#把 之前比较大小 脚本修改为read命令方式 16[root@manager ~]# cat /server/scripts/2.8-1-compread.sh 17#!/bin/bash 18#author: oldboy 19read -p "input num1 num2:" num1 num2 20#number 21#expr $num1 + $num2 + 1 &>/dev/null 22#[ $? -ne 0 ] && { 23[[ "$num1" =~ ^[0-9]+$ && "$num2" =~ ^[0-9]+$ ]] || { 24echo "Usage: Must have two number" 25exit 2 26} 27#compare 28[ $num1 -gt $num2 ] && echo "$num1 -gt $num2" 29[ $num1 -lt $num2 ] && echo "$num1 -lt $num2" 30[ $num1 -eq $num2 ] && echo "$num1 -eq $num2" 31[root@manager ~]# 32[root@manager ~]# sh /server/scripts/2.8-1-compread.sh 33input num1 num2:10 20 3410 -lt 20 35[root@manager ~]# sh /server/scripts/2.8-1-compread.sh 36input num1 num2:10 10b 37Usage: Must have two number 38[root@manager ~]# sh /server/scripts/2.8-1-compread.sh 39input num1 num2:10 40Usage: Must have two number 41[root@manager ~]# sh /server/scripts/2.8-1-compread.sh 42input num1 num2:20b 43Usage: Must have two number 44[root@manager ~]# sh /server/scripts/2.8-1-compread.sh 45input num1 num2: 46Usage: Must have two number 47 48

命令、脚本后台运行

让命令或脚本去后台运行 防止断网 远程连接工具突然断开

& 或 nohup command & ctrl + z 与 bg screen

1. & 或 nohup command &

1[root@manager ~]# sleep 99 & 2[1] 7965 3[root@manager ~]# ps -ef |grep sleep 4root 7965 7944 0 11:14 pts/0 00:00:00 sleep 599 6root 7967 7944 0 11:14 pts/0 00:00:00 grep 7--color=auto sleep 8 9

2. ctrl + z配合 bg

1#ctrl + z 让进程去后台挂起 (暂停) 2[root@manager ~]# sleep 666 3^Z 4[2]+ 已停止 sleep 666 5#bg 让后台挂起的 继续运行 background 6[root@manager ~]# bg 7[2]+ sleep 666 & 8[1] 完成 sleep 99 9#查看后台运行 10jobs 11#应用场景:杀掉 顽固进程 12##执行顽固进程 13##ctrl + z 14##kill %1 #数字 15 16

3. screen

1#screen基础用法 2screen 3xshell断开 4xshell重新连接 5[root@manager ~]# screen -ls 6There is a screen on: 7 7977.pts-0.manager (Detached) 81 Socket in /var/run/screen/S-root. 9[root@manager ~]# 10[root@manager ~]# 11[root@manager ~]# 12[root@manager ~]# 13#查看所有screen窗口 14[root@manager ~]# screen -ls 15There is a screen on: 16 7977.pts-0.manager (Detached) 17 1 Socket in /var/run/screen/S-root. 18#重新连接到指定窗口 19[root@manager ~]# screen -r 7977 20 21

快捷键:

1ctrl + a d 退出screen窗口 窗口会继续会继续运行 2ctrl + a k 结束当前screen窗口 3检查 自己是否在 screen中 ctrl +a v #version 4 5

判断

if 判断3种格式
1.单分支判断

在这里插入图片描述
# 单分支判断
应用在脚本开头 做检查,检查失败退出脚本 参数个数 脚本 命令是否有权限

1if [ 条件 ];then 2 命令 3fi 4 5

2. 双分支判断
在这里插入图片描述
#双分支判断
检查 服务 进程

1if [ 条件 ] 2then 3 命令 4else 5 命令 6fi 7 8

Example
检查 crond服务是否运行中 如果运行提示 crond is running 否则 提示 crond is failed
#后面检查服务的脚本 检查哪个服务脚本名字不要以服务命名

1[root@yida scripts]# cat check_cr.sh 2#!/bin/bash 3#检查 crond服务是否运行中 如果运行提示 crond is running 否则 提示 crond is failed 4. /etc/init.d/functions 5Name=$(ps -ef |grep crond |grep -vc grep) 6if [ $Name -ge 1 ];then 7 action "crond is running" /bin/true 8 9else 10 action "crond is failed" /bin/false 11fi 12 13

3. 多分支判断

1[root@manager ~]# vim /server/scripts/2.8-1-comp-readmulti-if.sh 2 3#!/bin/bash 4#author: oldboy 5read -p "input num1 num2:" num1 num2 6#number 7#expr $num1 + $num2 + 1 &>/dev/null 8#[ $? -ne 0 ] && { 9if [[ ! "$num1" =~ ^[0-9]+$ || ! "$num2" =~ ^[0-9]+$ 10]] 11then 12 echo "Usage: Must have two number" 13 exit 2 14fi 15#compare 16if [ $num1 -gt $num2 ] 17then 18 echo "$num1 -gt $num2" 19elif [ $num1 -lt $num2 ] #else if 20then 21 echo "$num1 -lt $num2" 22else 23 echo "$num1 -eq $num2" 24fi 25 26

在这里插入图片描述

服务检查方式及命令

端口 本地检查: netstat -lntup/ss -lntup /lsof -i:80

远程检查: telnet ip port /nc ip port /nmap 进程 ps -ef/ ps aux 客户端模拟监控 ping -c1 -i1 -W1 ip /curl /wget -q --spider 数据库 mysql -e 'show databases;'

端口检查

1#ss 或 netstat 2[root@manager ~]# ss -lntup |grep 22 3udp UNCONN 0 0 127.0.0.1:323 4 *:* users: 5(("chronyd",pid=5220,fd=1)) 6udp UNCONN 0 0 ::1:323 7 :::* users: 8(("chronyd",pid=5220,fd=2)) 9tcp LISTEN 0 128 *:22 10 *:* users: 11(("sshd",pid=7061,fd=3)) 12[root@manager ~]# ss -lntup |grep -w :22 13tcp LISTEN 0 128 *:22 14 *:* users: 15(("sshd",pid=7061,fd=3)) 16 17#lsof 18[root@manager ~]# lsof -i :22 19COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE 20NAME 21sshd 7061 root 3u IPv4 39278 0t0 TCP 22*:ssh (LISTEN) 23sshd 7322 root 3u IPv4 40265 0t0 TCP 24manager:ssh->10.0.0.100:49510 (ESTABLISHED) 25sshd 7392 root 3u IPv4 43630 0t0 TCP 26manager:ssh->10.0.0.100:50037 (ESTABLISHED) 27 28#nc telnet 29[root@manager ~]# telnet 10.0.0.61 22 30Trying 10.0.0.61... 31Connected to 10.0.0.61. 32Escape character is '^]'. 33SSH-2.0-OpenSSH_7.4 34Protocol mismatch. 35Connection closed by foreign host. 36[root@manager ~]# nc 10.0.0.61 22 37SSH-2.0-OpenSSH_7.4 38Protocol mismatch. 39 40#nmap 41nmap -p22 ip/url 42namp -p1-1024 ip/url #端口范围 1-65535 43nmap -p22,80 ip/url 44[root@manager ~]# nmap -p80 baidu.com 45Starting Nmap 6.40 ( http://nmap.org ) at 2020-01-14 4609:29 CST 47Nmap scan report for baidu.com (220.181.38.148) 48Host is up (0.0088s latency). 49Other addresses for baidu.com (not scanned): 5039.156.69.79 51PORT STATE SERVICE 5280/tcp open http 53Nmap done: 1 IP address (1 host up) scanned in 0.21 54seconds 55 56

模拟用户访问网站

1[root@manager ~]# wget --spider www.oldbing.com 2开启 Spider 模式。检查是否存在远程文件。 3--2020-01-14 09:38:43-- http://www.oldbing.com/ 4正在解析主机 www.oldbing.com (www.oldbing.com)... 失败: 5未知的名称或服务。 6wget: 无法解析主机地址 “www.oldbing.com” 7[root@manager ~]# echo $? 84 9[root@manager ~]# wget -q(定向为空) --spider www.oldbing.com 10[root@manager ~]# echo $? 114 12 13

面试题
1. 通过脚本传参的方式,检查Web网站URL是否正常

1[root@m01 /scripts]# cat check_url.sh 2#!/bin/bash 3url=$1 4 5if ping -c1 $url &>/dev/null;then 6 echo "$url is ok" 7else 8 echo "$url is failed" 9fi 10 11

2. 通过脚本传参的方式,检查Web网站URL是否正常

1[root@m01 /scripts]# cat check_url2.sh 2#!/bin/bash 3url=$1 4if [[ ! "$url" =~ ^[a-zA-Z.]*[a-zA-Z0-9]+\.(com|org|cn)$ ]] 5then 6 echo "$url is not ok" 7 exit 1 8fi 9#wget url 10wget -T 1 -q --spider $url 11if [ $? -eq 0 ] 12then 13 echo $url is ok 14else 15 echo $url is failed 16fi 17 18

3. 检查系统可用内存
企业案例:监控系统可用内存,小于100M就发送报警邮件 否则,提示内存充足,定时任务每3分钟1次

1[root@manager ~]# cat /server/scripts/2.10.2- 2chk_mem.sh 3#!/bin/bash 4#author:oldboy 5mem=`free -m |awk 'NR==2{print $NF}'` 6if [ $mem -lt 10000 ] 7then 8 mail -s "mem is bugoule" 918391635@qq.com </etc/hosts 9fi 10[root@manager ~]# sh /server/scripts/2.10.2-chk_mem.sh 11[root@manager ~]# crontab -l 12#check mem by liyy at 20200202 13*/3 * * * * /bin/sh /server/scripts/2.10.2-chk_mem.sh &>/dev/null 14 15

服务管理类脚本

1. 服务管理脚本书写

rsync

1目标:书写 服务管理脚本 2分步: 3基础要求: 4sh rsyncd.sh start 5sh rsyncd.sh stop 6sh rsyncd.sh restart 7进阶: 8rsync服务开机自启动 9 10
1#rsync管理命令 2### sh rsyncd.sh start === rsync --daemon 3 #rsyncd sshd crond 4 ### sh rsyncd.sh stop === kill `cat 5pidfile` 6### sh rsyncd.sh restart === stop start 7#准备 rsync的配置文件 8#Rsync server 9#created by oldboy 15:01 2009-6-5 10##rsyncd.conf start## 11uid = root 12gid = root 13use chroot = no 14max connections = 2000 15timeout = 600 16pid file = /var/run/rsyncd.pid 17lock file = /var/run/rsync.lock 18log file = /var/log/rsyncd.log 19ignore errors 20read only = false 21list = false 22hosts allow = 10.0.0.0/24 23hosts deny = 0.0.0.0/32 24auth users = rsync_backup 25secrets file = /etc/rsync.password 26##################################### 27[www] 28comment = www by old0boy 14:18 2012-1-13 29path = /oldboy 30[root@oldboyedu-c6 ~]# rsync --daemon 31[root@oldboyedu-c6 ~]# ss -lntup |grep 873 32tcp LISTEN 0 5 :::873 33 :::* users:(("rsync",2364,5)) 34tcp LISTEN 0 5 *:873 35 *:* users:(("rsync",2364,3)) 36[root@oldboyedu-c6 ~]# 37[root@oldboyedu-c6 ~]# kill `cat /var/run/rsyncd.pid` 38[root@oldboyedu-c6 ~]# ss -lntup |grep 873 39 40

在这里插入图片描述
#服务管理脚本 基本形式

1[root@oldboyedu-c6 /server/scripts]# vim rsyncd.sh 2#!/bin/bash 3choice=$1 4if [ "$choice" = "start" ] 5then 6 rsync --daemon 7fi 8if [ "$choice" = "stop" ] 9then 10 kill `cat /var/run/rsyncd.pid` 11fi 12if [ "$choice" = "restart" ] 13then 14 kill `cat /var/run/rsyncd.pid` 15 sleep 1 16 rsync --daemon 17fi 18"rsyncd.sh" [New] 20L, 254C written 19 20[root@oldboyedu-c6 /server/scripts]# 21[root@oldboyedu-c6 /server/scripts]# sh rsyncd.sh 22[root@oldboyedu-c6 /server/scripts]# pkill rsyncd 23[root@oldboyedu-c6 /server/scripts]# pkill rsync 24[root@oldboyedu-c6 /server/scripts]# ss -lntup |grep 25873 26[root@oldboyedu-c6 /server/scripts]# sh rsyncd.sh 27start 28[root@oldboyedu-c6 /server/scripts]# ss -lntup |grep 29873 30tcp LISTEN 0 5 :::873 31 :::* users:(("rsync",3947,5)) 32tcp LISTEN 0 5 *:873 33 *:* users:(("rsync",3947,3)) 34 35

在这里插入图片描述
在这里插入图片描述

让脚本(服务能开机自启动)或通过service管理

方法1 /etc/rc.local (centos 7 ) 需要加上 执行权限
方法2 通过chkconfig(c6) 管理 或 systemctl管理(c7)

chkconfig管理脚本要求
脚本必须放在 /etc/init.d/ 并且 有执行权限
脚本开头 必须要有chkconfig要求的格式
#chkconfig: 2345(运行级别) 99 98 99开机顺序 98关机顺序
添加到chkconfig管理 : chkconfig --add rsyncd.sh

CentOS 6.x 方法

#chkconfig 管理开机自启动

1[root@oldboyedu-c6 /server/scripts]# chkconfig |grep ipt 2iptables 0:off 1:off 2:on 3:on 4:on 35:on 6:off 4[root@oldboyedu-c6 /server/scripts]# chkconfig 5iptables off 6[root@oldboyedu-c6 /server/scripts]# 7[root@oldboyedu-c6 /server/scripts]# chkconfig |grep ipt 8iptables 0:off 1:off 2:off 3:off 4:off 95:off 6:off 10 11

#chkconfig管理 服务脚本 实现开机自启动
###1. 脚本必须放在 /etc/init.d/ 并且 有执行权限

1[root@oldboyedu-c6 /server/scripts]# mv rsyncd.sh 2/etc/init.d/ 3[root@oldboyedu-c6 /server/scripts]# chmod +x 4/etc/init.d/rsyncd.sh 5[root@oldboyedu-c6 /server/scripts]# ll 6/etc/init.d/rsyncd.sh 7-rwxr-xr-x. 1 root root 342 Jan 14 15:28 8/etc/init.d/rsyncd.sh 9 10

###2. 脚本开头 必须要有chkconfig要求的格式

1[root@oldboyedu-c6 /server/scripts]# head -2 2/etc/init.d/rsyncd.sh 3#!/bin/bash 4# chkconfig: 2345 99 98 5 6

###3. 添加到chkconfig管理 :

1`
chkconfig --add rsyncd.sh

1[root@oldboyedu-c6 /server/scripts]# chkconfig --add 2rsyncd.sh 3[root@oldboyedu-c6 /server/scripts]# chkconfig |grep 4rsync 5rsyncd.sh 0:off 1:off 2:on 3:on 4:on 65:on 6:off 7 8

CentOS 7.x 8.x systemctl 管理方法

#环境准备

1[root@manager ~]# cat /etc/rsyncd.conf 2#Rsync server 3#created by oldboy 15:01 2009-6-5 4##rsyncd.conf start## 5uid = root 6gid = root 7use chroot = no 8max connections = 2000 9timeout = 600 10pid file = /var/run/rsyncd.pid 11lock file = /var/run/rsync.lock 12log file = /var/log/rsyncd.log 13ignore errors 14read only = false 15list = false 16hosts allow = 10.0.0.0/24 17hosts deny = 0.0.0.0/32 18auth users = rsync_backup 19secrets file = /etc/rsync.password 20##################################### 21[www] 22comment = www by old0boy 14:18 2012-1-13 23path = /oldboy 24[root@manager ~]# systemctl disable rsyncd 25[root@manager ~]# systemctl stop rsyncd 26 27

#准备管理脚本

1[root@manager ~]# scp 210.0.0.202:/etc/init.d/rsyncd.sh /etc/init.d/ 3root@10.0.0.202's password: 4rsyncd.sh 5 100% 384 321.1KB/s 00:00 6 7[root@manager ~]# ss -lntup |grep 873 8[root@manager ~]# uname -r 93.10.0-957.el7.x86_64 10[root@manager ~]# /etc/init.d/rsyncd.sh start 11[root@manager ~]# ss -lntup |grep 873 12tcp LISTEN 0 5 *:873 13 *:* users: 14(("rsync",pid=11087,fd=3)) 15tcp LISTEN 0 5 :::873 16 :::* users: 17(("rsync",pid=11087,fd=5)) 18[root@manager ~]# /etc/init.d/rsyncd.sh stop 19[root@manager ~]# ss -lntup |grep 873 20[root@manager ~]# /etc/init.d/rsyncd.sh restart 21[root@manager ~]# 22[root@manager ~]# 23[root@manager ~]# ss -lntup |grep 873 24tcp LISTEN 0 5 *:873 25 *:* users: 26(("rsync",pid=11097,fd=3)) 27tcp LISTEN 0 5 :::873 28 :::* users: 29(("rsync",pid=11097,fd=5) 30 31

#书写systemctl配置
systemctl cat rsyncd
systemctl cat nginx

1[root@manager ~]# systemctl cat nginx.service 2# /usr/lib/systemd/system/nginx.service 3[Unit] 4Description=The nginx HTTP and reverse proxy server 5After=network.target remote-fs.target nsslookup.target 6[Service] 7Type=forking 8PIDFile=/run/nginx.pid 9#Nginx will fail to start if /run/nginx.pid already 10exists but has the wrong 11#SELinux context. This might happen when running 12`nginx -t` from the cmdline. 13#https://bugzilla.redhat.com/show_bug.cgi?id=1268621 14ExecStartPre=/usr/bin/rm -f /run/nginx.pid 15ExecStartPre=/usr/sbin/nginx -t 16ExecStart=/usr/sbin/nginx 17ExecReload=/bin/kill -s HUP $MAINPID #nginx -s 18reload 19ExecStop= 20KillSignal=SIGQUIT 21TimeoutStopSec=5 22KillMode=process 23PrivateTmp=true 24[Install] 25WantedBy=multi-user.target 26 27

[Unit]

  1. 说明信息 2. 依赖关系 After 在后面服务之后运行

[Service]

  1. 说明 start stop restart 对应的命令或脚本ExecStart ExecStop ExecReload 2. 类型 Type=forking 服务模式

[Install] 运行级别(target)

1[root@manager ~]# cat 2/usr/lib/systemd/system/rsyncd-new.service 3[Unit] 4After=network.target remote-fs.target 5[Service] 6Type=forking 7ExecStart=/etc/init.d/rsyncd.sh start 8ExecStop=/etc/init.d/rsyncd.sh stop 9ExecReload=/etc/init.d/rsyncd.sh restart 10[Install] 11WantedBy=multi-user.target 12[root@manager ~]# pkill rsync 13[root@manager ~]# pkill rsync 14[root@manager ~]# systemctl start rsyncd-new.service 15[root@manager ~]# systemctl status rsyncd-new.service 16● rsyncd-new.service 17 Loaded: loaded (/usr/lib/systemd/system/rsyncdnew.service; disabled; vendor preset: disabled) 18 Active: active (running) since 二 2020-01-14 1916:10:58 CST; 9s ago 20 Process: 11339 ExecStart=/etc/init.d/rsyncd.sh start 21(code=exited, status=0/SUCCESS) 22 Main PID: 11341 (rsync) 23 CGroup: /system.slice/rsyncd-new.service 24 └─11341 rsync --daemon 25114 16:10:58 manager systemd[1]: Starting rsyncdnew.service... 26114 16:10:58 manager systemd[1]: Started rsyncdnew.service. 27[root@manager ~]# 28[root@manager ~]# systemctl enable rsyncd-new.service 29Created symlink from /etc/systemd/system/multiuser.target.wants/rsyncd-new.service to 30/usr/lib/systemd/system/rsyncd-new.service. 31[root@manager ~]# 32[root@manager ~]# 33[root@manager ~]# systemctl status rsyncd-new.service 34● rsyncd-new.service 35 Loaded: loaded (/usr/lib/systemd/system/rsyncdnew.service; enabled; vendor preset: disabled) 36 Active: active (running) since 二 2020-01-14 3716:10:58 CST; 37s ago 38 Main PID: 11341 (rsync) 39 CGroup: /system.slice/rsyncd-new.service 40 └─11341 rsync --daemon 41114 16:10:58 manager systemd[1]: Starting rsyncdnew.service... 42114 16:10:58 manager systemd[1]: Started rsyncdnew.service. 43 44

小结

Linux各种服务软件 管理脚本

11. 找出 服务 start |stop|restart 对应的命令 22. 书写脚本 if 33. 服务开机自启动systemctl/chkconfig 4 5

case语句

分支结构 条件选择语句
应用场景: 服务管理脚本(start|stop|restart) 菜单功能

#格式

1case "选择" in 2 条件1) 3 命令 4 ;; 5 条件2) 6 命令 7 ;; 8 *) 9 默认的内容 10esac 11 12

#案例

1[root@manager ~]# vim /server/scripts/2.12-1-case.sh 2 3#!/bin/bash 4#author: oldboy 5choice=$1 6case "$choice" in 7 start) 8 echo start 9 ;; 10 stop) 11 echo stop 12 ;; 13 restart) 14 echo restart 15 ;; 16 *) 17 echo "Usages: $0 {start|stop|restart}" 18 exit 1 19esac 20 21

sh与source(.)

sh(bash) 都可以运行脚本 运行的时候会创建1个子shell 通用执行脚本方法 source(.) 都可以运行脚本 是在当前shell环境运行 加载 /etc/init.d/functions 系统的函数库 source/etc/init.d/functions

在这里插入图片描述

1[root@manager /server/scripts]# cat 2.13-1-shsource.sh 2#!/bin/bash 3#author:oldboy 4echo $OLDBOY 5[root@manager /server/scripts]# OLDBOY=666 6[root@manager /server/scripts]# sh 2.13-1-sh-source.sh 7[root@manager /server/scripts]# . 2.13-1-sh-source.sh 8666 9 10

函数

别名 :给命令或脚本设置别名 alias rm='echo oldboy’

函数:给一段代码设置1个名称 ,代码:函数体 名称:函数名字 (专业 规范)

函数的基础格式

#格式
##格式1

1function 函数名() { 2函数体(命令) 3函数体(命令) 4return 5} 6 7

##格式2

1function 函数名 { 2函数体(命令) 3函数体(命令) 4return 5} 6 7

##格式3 ※※※※※

1函数名() { 2函数体(命令) 3函数体(命令) 4return 5} 6 7

函数传参

$1 $2 $数字 脚本的第1个 第2个 参数 函数的第1个 第2个 参数 $0 脚本名字 脚本名字 $# 脚本参数个数 函数参数的个数 $* 取出脚本所有的参数 取出函数所有的参数 $@ 取出脚本所有的参数 取出函数所有的参数

1[root@manager /server/scripts]# cat 2.14.2-rsyncd.sh 2#!/bin/bash 3# chkconfig: 2345 99 98 4# author:oldboy 5choice=$1 6pidfile=/var/run/rsyncd.pid 7start() { 8 [ -f $pidfile ] || rsync --daemon 9} 10stop() { 11 [ -f $pidfile ] && kill `cat 12/var/run/rsyncd.pid` 13} 14restart() { 15 [ -f $pidfile ] && kill `cat 16/var/run/rsyncd.pid` 17 sleep 1 18 rsync --daemon 19} 20case "$choice" in 21 start) 22 start 23 ;; 24 stop) 25 stop 26 ;; 27 restart) 28 restart 29 ;; 30 *) 31 echo "Usage $0 {start|stop|restart}" 32 exit 1 33esac 34 35

循环语句

while当型循环 基础

while 当型循环 死循环,读取文件的内容

#while 循环

1while 条件 2do 3 命令 4done 5 6
1[root@manager /server/scripts]# cat 2.15.1- 2while.sh 3#!/bin/bash 4#author:oldboy 5while true #死循环 true 条件永久成立 6do 7 date 8 sleep 2 9done 10 11

#eg: 使用while循环 输出1 2 3 … 10 类似 seq 10

1[root@manager /server/scripts]# vim 2.15.2-seqwhile.sh 2 3#!/bin/bash 4#author:oldboy 5i=0 6while [ $i -lt 10 ] 7do 8 ((i++)) 9 echo $i 10done 11 12

#面试题: 计算1+2+3+4+5…+10 求总和
###方法1: while

1[root@manager /server/scripts]# cat 2.15.3-sumwhile.sh 2#!/bin/bash 3#author:oldboy 4i=1 5sum=0 6while [ $i -le 10 ] 7do 8 ((sum=sum+i)) 9 ((i++)) 10done 11echo $sum 12 13

###方法2:

1[root@manager /server/scripts]# echo $((`seq -s+ 10` )) 255 3[root@manager /server/scripts]# seq -s+ 10 41+2+3+4+5+6+7+8+9+10 5[root@manager /server/scripts]# seq -s+ 10 |bc 655 7 8

#脚本修改为函数 并且使用while 死循环

1[root@manager /server/scripts]# cat 2.8-1-comp-readmulti-if.sh 2#!/bin/bash 3#author: oldboy 4read -p "input num1 num2:" num1 num2 5if [[ ! "$num1" =~ ^[0-9]+$ || ! "$num2" =~ ^[0-9]+$ 6]] 7then 8 echo "Usage: Must have two number" 9 exit 2 10fi 11#compare 12if [ $num1 -gt $num2 ] 13then 14 echo "$num1 -gt $num2" 15elif [ $num1 -lt $num2 ] #else if 16then 17 echo "$num1 -lt $num2" 18else 19 echo "$num1 -eq $num2" 20fi 21 22
1[root@manager /server/scripts]# cat 2.15.3-comp-readmulti-if.sh 2#!/bin/bash 3#author: oldboy 4input() { 5read -p "input num1 num2:" num1 num2 6} 7#number 8#expr $num1 + $num2 + 1 &>/dev/null 9#[ $? -ne 0 ] && { 10check() { 11if [[ ! "$num1" =~ ^[0-9]+$ || ! "$num2" =~ ^[0-9]+$ 12]] 13then 14 echo "Usage: Must have two number" 15 continue 16fi 17} 18#compare 19compare() { 20if [ $num1 -gt $num2 ] 21then 22 echo "$num1 -gt $num2" 23elif [ $num1 -lt $num2 ] #else if 24then 25 echo "$num1 -lt $num2" 26else 27 echo "$num1 -eq $num2" 28fi 29} 30main() { 31while true 32do 33 input 34 check 35 compare 36done 37} 38main 39 40

while 当型循环 读取文件

通过while read读取文件内容 ip 把ip通过iptables 封掉

#方式1:采用exec读取文件后,然后进入while循环处理

1exec<FILE 2while read line 3do 4 cmd 5done 6 7

#方式2:使用cat读取文件内容,然后通过管道进入while循环处理

1cat FILE|while read line 2do 3 cmd 4done 5 6

#※※※※※※方式3:在while循环结尾done通过输入重定向指定读取的文件

1while read line 2do 3 cmd 4done<FILE 5 6

#eg: while read line

1[root@m01 /server/scripts]# cat stu.txt 201 oldbing 18 302 oldxia 19 403 oldlidao 19 504 oldguo 66 6 7

##通过while循环 求和 stu.txt第3列的内容

1[root@manager /server/scripts]# cat 2.15.5-whileread-sum.sh 2#!/bin/bash 3#author:oldboy 4file=/server/scripts/stu.txt 5sum=0 6while read line 7do 8 num=`echo $line|awk '{print $3}'` 9 ((sum+=num)) #sum=sum+num 10done <$file 11echo $sum 12 13

###企业案例:写一个Shell脚本解决类DDOS攻击的生产案例。请根据web日志或者或者系统网络连接数,监控当某个IP并发连接数,若短时内并发连接数达到100(阈值),即调用防火墙命令封掉对应的IP。防火墙命令为:iptables -I INPUT -s IP地址 -j DROP。

1分析: 2 1.通过awk分析日志、连接数 每个ip的次数 结果存放在文件中 3 2.通过while read line 读取文件 4 5判断次数如果大于100 并且 iptables -nL中没有这个ip 则封掉 6DOS Denial of Service 拒绝式服务攻击 7DDOS 分布式 8系统网络连接数:ss -ant /netstat -ant 9分析netstat.log找出每个ip的连接数量(出现次数) 10如果次数大于100则通过iptables封掉 11 12
1[root@m01 /scripts]# cat check_while.sh 2#!/bin/bash 3 4file=/root/netstat.log 5tmp_file=/scripts/tmp.txt 6awk -F'[ :]+' '/ESTABLISHED/ {print $6}' $file |sort |uniq -c |sort -n > $tmp_file 7 8while read line;do 9 count=`echo $line |awk '{print $1}'` 10 ip=`echo $line |awk '{print $2}'` 11 if [ "$count" -gt 2 -a `iptables -nL |grep -wc $ip` -eq 0 ];then 12 iptables -I INPUT -s $ip -j DROP 13 fi 14done <$tmp_file 15 16
1[root@manager ~]# while read x y z 2> do 3> echo "x:"$x "y:"$y "z:$z" 4> done </server/scripts/stu.txt 5x:01 y:oldbing z:18 6x:02 y:oldxia z:19 7x:03 y:oldlidao z:19 8x:04 y:oldguo z:66 9[root@manager ~]# while read x y ; do echo "x:$x 10y:$y"; done </server/scripts/stu.txt 11x:01 y:oldbing 18 12x:02 y:oldxia 19 13x:03 y:oldlidao 19 14x:04 y:oldguo 66 15 16

while小结

11. 死循环 while true ; do ;done while : ; do 2;done 3 42. while读取文件的内容 5 6

直到型循环 until

1until 话费是否充足 2do 3 发短信 4done 5 6

for型循环

通用

1for n in 列表(名单) 2do 3命令 4done 5 6

数字循环(C语言循环)

1for((i=1;i<=10;i++)) 2do 3命令 4done 5 6

#生成随机字符 数字方法
##方法1 RANDOM

1[root@manager ~]# echo $RANDOM 214966 3[root@manager ~]# 4[root@manager ~]# 5[root@manager ~]# echo $((RANDOM + 100000)) 6125107 7 8

##方法2 date + md5sum

1[root@manager ~]# date +%N |md5sum| cut -c 1-8 27d178a23 3 4

##方法3 tr + /dev/urandom
###/dev/urandom 字符文件、字符设备 不断输出字符

1[root@manager ~]# tr -cd 'a-zA-Z0-9' </dev/urandom 2|head -c8 3for n in 1 2 3 4 {1..10} `seq 10` {1..10..2} 4`seq 1 2 10` 5do 6 echo $n 7done 8 9

#批量创建文件
企业面试题2:
使用for循环在/oldboy目录下通过随机小写10个字母加固定字符串oldboy批量创建10个html文件

1#!/bin/bash 2[ -d /oldboy ] || mkdir /oldboy 3for i in {1..10};do 4 name=`uuidgen |sed "s#[0-9-]##g" |head -c10` 5 touch /oldboy/${name}_oldboy.html 6done 7 8
1#!/bin/bash 2#author:oldboy 3dir=/oldboy 4[ -d "$dir" ] || mkdir -p $dir 5for n in {1..10} 6do 7 name=`tr -cd 'a-zA-Z' </dev/urandom |head -c10` 8 touch $dir/${name}_oldboy.html 9done 10 11

#批量重命名 把上面创建的文件名中 oldboy替换为 oldgirl

1#!/bin/bash 2cd /oldboy 3for n in `ls *`;do 4 rename html txt * 5done 6 7
1#!/bin/bash 2cd /oldboy 3for n in `ls *`;do 4 mv $n ${n/oldgirl/oldboy} 5done 6 7

#批量添加用户
企业面试题4:
##批量创建10个系统帐号oldboy01-oldboy10并设置密码(密码为随机8位字符串)

1#!/bin/bash 2for user in oldboy{01..10};do 3useradd $user 4num=`uuidgen |head -c 8` 5echo $num |passwd --stdin $user 6echo $user $num >> /scripts/tmp_user.txt 7done 8 9
1#!/bin/bash 2for n in oldboy{01..10} 3do 4 useradd $n 5 pass=`tr -cd 'a-zA-Z' </dev/urandom |head -c8` 6 echo "$pass" |passwd --stdin $n 7 echo $n $pass >>/root/pass.txt 8done 9 10

流程控制语句

return 函数中 在函数执行完成后 给函数返回值 函数中 在函数执行完成后 给函数返回值 exit 直接退出脚本 返回值 书写在 脚本报错的时候 提示信息然后退出脚本 continue n 控制循环 结束本次循环 进行下次循环 循环中跳过 break n 跳过所有循环

1checkpid() { 2local i #设置局部变量i 3for i in $* ; do #函数所有参数 循环 4[ -d "/proc/$i" ] && return 0 5done 6return 1 7} 8函数checkpid 9checkpid 10如果这个pid存在 return 0 11 12

#continue 基本含义

1[root@m01 ~]# for n in {1..5}; do [ $n -eq 3 ] &&continue ; echo $n ;done 21 32 44 55 6 7
1for pid in $pids ; do 2[ ! -e "/proc/$pid" ] && continue #如果pid目录不存在 则跳过本次循环 读取下1个pid目录 3 4

#break 基本含义

1[root@manager ~]# for n in {1..10}; do [ $n -eq 5 ]&&break ; echo $n ;done 21 32 43 54 6 7

#continue break 扩展
#continue 2 结束当前循环跳到第2层循环 从第2层循环开始

1for n in {A..E} 2do 3for m in {a..e} 4do 5for i in {1..5} 6do 7echo $n $m $i 8done 9done 10done 11 12
1for n in {A..E} 2do 3for m in {a..e} 4do 5for i in {1..5} 6do 7[ $i -eq 3 ] &&continue 8echo $n $m $i 9done 10done 11done 12 13
1for n in {A..E} 2do 3for m in {a..e} 4do 5for i in {1..5} 6do 7[ $i -eq 3 ] &&continue 2 8echo $n $m $i 9done 10done 11done 12 13

#break 2

1for n in {A..E} 2do 3for m in {a..e} 4do 5for i in {1..5} 6do 7[ $i -eq 4 ] &&break 2 8echo $n $m $i 9done 10done 11done 12 13

eg:乘法口诀表
精确

1for i in {1..9} 2do 3for((j=1;j<=i;j++)) 4do 5echo "$j*$i=$((i*j))" 6done 7done 8 9

精确加上格式

1for i in {1..9} 2do 3for((j=1;j<=i;j++)) 4do 5echo -n "$j*$i=$((i*j)) " 6done 7echo 8done |column -t 9 10

Linux加上颜色与vimrc

颜色

Linux命令行给字体加颜色命令

1[root@oldboy scripts]# echo -e "\E[1;31m红色字 2oldboy\E[0m" 3红色字oldboy 4[root@oldboy scripts]# echo -e "\033[31m红色字oldboy 5\033[0m" 6 7

在上述命令中:

1echo -e可以识别转义字符,这里将识别特殊字符的含义,并输出。 2\n \t 3Linux下面回车是 \n 4Windows下面回车是 \r\n 5#巨坑: windows下面书写脚本或SQL语句 放入到linux执行 失败 6#解决: dos2unix 7 8

\E也可以使用\033替代


[1数字1表示加粗显示(这个位置可以加不同的数字代表不同的意思,详细信息可man console_codes得)


31m表示为红色字体,这个位置可以换不同的数字,以代表不同的意思


“红色字oldboy”表示待设置的内容


[0m表示关闭所有属性,这个位置可以换不同的数字,以代表不同的意思


1echo -e "\E[5;31m红色字oldboy\E[0m" 2echo -e "\E[5;32m绿色字oldboy\E[0m" 3echo -e "\E[5;33m棕色字oldboy\E[0m" 4echo -e "\E[5;34m颜色字oldboy\E[0m" 5echo -e "\E[5;35m紫色/红色oldboy\E[0m" 6 7

在这里插入图片描述

1[root@manager ~]# echo -e "\E[1;31m红色字oldboy\E[0m" 2红色字oldboy 3[root@manager ~]# echo -e "\E[1;31;42m红色字绿色背景 4oldboy\E[0m" 5红色字绿色背景oldboy 6[root@manager ~]# echo -e "\E[5;31;42m红色字绿色背景 闪烁 7oldboy\E[0m" 8 9

红色字绿色背景 闪烁oldboy

在这里插入图片描述


案例
sh color.sh 执行脚本后 给 内容加上对应的颜色
1.input red 内容
2.input green 内容
3.input blue 内容
例子:选择1 oldboy
则oldboy显示为红色

1[root@manager ~]# cat /server/scripts/2.18.1-color.sh 2#!/bin/bash 3#author:oldboy 4RED="\E[1;31m" 5GREEN="\E[1;32m" 6BLUE="\E[1;34m" 7END="\E[0m" 8input() { 9cat <<EOF 101.input red 内容 112.input green 内容 123.input blue 内容 13EOF 14read -p "input choice:" cho 15read -p "内容:" text 16} 17choice() { 18case "$cho" in 191) 20echo -e "${RED} $text ${END}" 21;; 222) 23echo -e "${GREEN} $text ${END}" 24;; 253) 26echo -e "${BLUE} $text ${END}" 27;; 28*) 29echo "Usage: input {1|2|3}" 30exit 1 31esac 32} 33main() { 34input 35choice 36} 37main 38 39
1[root@m01 /scripts]# cat test.sh 2#!/bin/bash 3red="\e[1;31m" 4green="\e[1;32m" 5blue="\e[1;34m" 6end="\e[0m" 7 8while true;do 9 echo "1.input red 内容" 10 echo "2.input green 内容" 11 echo "3.input blue 内容" 12 read -p "please input number:" choice 13 if [ $choice -le 3 ];then 14 read -p "内容:" text 15 fi 16 case $choice in 17 1) 18 echo -e "${red}${text}${end}" 19 exit 1 20 ;; 21 2) 22 echo -e "${green}${text}${end}" 23 exit 1 24 ;; 25 3) 26 echo -e "${blue}${text}${end}" 27 exit 1 28 ;; 29 *) 30 if [ $choice -gt 3 ];then 31 echo "请输入正确编号" 32 fi 33 esac 34done 35 36

vimrc

通过vim编辑文件的配置文件
创建新文件 .sh 文件 自动加上版权说明


vim格式
##简易版本

1#创建新文件 .sh 文件 自动加上版权说明 2##/etc/vimrc 全局 3##~/.vimrc 当前用户生效 √√√√√ 4 5 6autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call 7SetTitle()" 8func SetTitle() 9if expand("%:e") == 'sh' 10call setline(1,"#!/bin/bash") 11call setline(2, 12"##################################################### 13#########") 14call setline(3, "# File Name: ".expand("%")) 15call setline(4, "# Version: V1.0") 16call setline(5, "# Author: oldboy") 17call setline(6, "# Organization: 18www.oldboyedu.com") 19call setline(7, "# Created Time : 20".strftime("%F %T")) 21call setline(8, "# Description:") 22call setline(9, 23"##################################################### 24#########") 25call setline(10, "") 26endif 27endfunc 28 29

##完整的配置

1###vim 给光标所在行 加上提示 下划线 2###tab键 修改为 4个空个长度 3###自动 缩进 自动对齐 4 5set nocompatible 6set history=100 7filetype on 8filetype plugin on 9filetype indent on 10set autoread 11set mouse=c 12syntax enable 13set cursorline 14hi cursorline guibg=#00ff00 15hi CursorColumn guibg=#00ff00 16set foldenable 17set foldmethod=manual 18set foldcolumn=0 19setlocal foldlevel=3 20set foldclose=all 21nnoremap <space> @=((foldclosed(line('.')) < 0) ? 'zc' 22: 'zo')<CR> 23set expandtab 24set tabstop=4 25set shiftwidth=4 26set softtabstop=4 27set smarttab 28set ai 29set si 30set wrap 31set sw=4 32set wildmenu 33set ruler 34set cmdheight=1 35set lz 36set backspace=eol,start,indent 37set whichwrap+=<,>,h,l 38set magic 39set noerrorbells 40set novisualbell 41set showmatch 42set mat=4 43set hlsearch 44set ignorecase 45set encoding=utf-8 46set fileencodings=utf-8 47set termencoding=utf-8 48set smartindent 49set cin 50set showmatch 51set guioptions-=T 52set guioptions-=m 53set vb t_vb= 54set laststatus=4 55set pastetoggle=<F9> 56set background=dark 57highlight Search ctermbg=black ctermfg=white 58guifg=white guibg=black 59autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call 60SetTitle()" 61func SetTitle() 62if expand("%:e") == 'sh' 63call setline(1,"#!/bin/bash") 64call setline(2, 65"##################################################### 66#########") 67call setline(3, "# File Name: ".expand("%")) 68call setline(4, "# Version: V1.0") 69call setline(5, "# Author: oldboy") 70call setline(6, "# Organization: 71www.oldboyedu.com") 72call setline(7, "# Created Time : 73".strftime("%F %T")) 74call setline(8, "# Description:") 75call setline(9, 76"##################################################### 77#########") 78call setline(10, "") 79endif 80endfunc 81 82

shell数组

ip1=10.0.0.7
ip2=10.0.0.8
ip3=192.168.1.20
echo $ip1 $ip2 $ip3

1#存放或使用 没有太多规律的信息 2#使用shell数组 3#array[1] 4#数组名称[下标] #数组名称[元素名称] 5 6[root@manager ~]# 7[root@manager ~]# array[1]=10.0.0.7 8[root@manager ~]# array[2]=10.0.0.61 9[root@manager ~]# 10[root@manager ~]# echo ${array[1]} 1110.0.0.7 12[root@manager ~]# echo ${array[*]} 1310.0.0.7 10.0.0.61 14 15

数组的赋值方式
在这里插入图片描述
#手动批量创建 数组

1[root@manager ~]# lidao=(oldboy alex oldbing) 2[root@manager ~]# echo ${lidao[1]} 3alex 4[root@manager ~]# echo ${lidao[0]} 5oldboy 6[root@manager ~]# echo ${lidao[1]} 7alex 8[root@manager ~]# 9[root@manager ~]# echo ${lidao[*]} 10oldboy alex oldbing 11 12

#通过文件创建 数组

1[root@manager ~]# name=(`awk -F: '{print $1}' 2/etc/passwd`) 3[root@manager ~]# echo ${name[0]} 4root 5[root@manager ~]# echo ${name[*]} 6root bin daemon adm lp sync shutdown halt mail 7operator games ftp nobody systemd-network dbus polkitd 8tss abrt sshd postfix chrony ntp oldboy nginx tcpdump 9mysql oldboy01 oldboy02 oldboy03 oldboy04 oldboy05 10oldboy06 oldboy07 oldboy08 oldboy09 oldboy10 11[root@manager ~]# echo ${#name[*]} 1236 13 14

eg:
环境

1cat >/server/scripts/ip_list.txt<<EOF 210.0.0.61 310.0.0.71 410.0.0.81 510.0.0.202 6EOF 7 8

#检查文件中 指定的ip是否存在(ping通)
#方法1

1cat /server/scripts/2.19.1-chk-ip.sh 2#!/bin/bash 3ip_list=( `cat /server/scripts/ip_list.txt` ) 4check_ip() { 5ping -c1 -i1 -W1 $ip &>/dev/null 6if [ $? -eq 0 ];then 7echo "$ip is ok" 8else 9echo "$ip is failed" 10fi 11} 12main() { 13for ip in ${ip_list[*]} 14do 15check_ip 16done 17} 18main 19 20

#方法2

1[root@manager ~]# ip_list=(`cat/server/scripts/ip_list.txt`) 2[root@manager ~]# echo ${ip_list[*]} 310.0.0.61 10.0.0.71 10.0.0.81 10.0.0.202 4[root@manager ~]# for((i=0;i<${#ip_list[*]};i++));do 5echo ${ip_list[i]} ;done 610.0.0.61 710.0.0.71 810.0.0.81 910.0.0.202 10[root@manager ~]# for ip in ${ip_list[*]}; do echo 11$ip ;done 1210.0.0.61 1310.0.0.71 1410.0.0.81 1510.0.0.202 16 17

shell总结

1# Log that something succeeded 2success() { 3[ "$BOOTUP" != "verbose" -a -z "${LSB:-}" ] && 4echo_success 5return 0 6} 7action() { 8local STRING rc #创建变量 9STRING=$1 #函数第1个参数赋值给 STRING="ip is ok" 10echo -n "$STRING " #显示 变量内容 不换行 11shift #移动脚本或函数的参数 #执行后 12$1是 /bin/true 13"$@" && success $"$STRING" || failure $"$STRING" 14#/bin/true && success || failure ` 15#success 显示 [OK] [确定] 16rc=$? #命令执行结果 17echo 18return $rc 19} 20action "ip is ok" /bin/true 21#屏幕输出 22ip is ok [OK] 23#补充 24[root@manager ~]# set oldboy alex 25[root@manager ~]# echo $1 $2 26oldboy alex 27[root@manager ~]# shift 28[root@manager ~]# echo $1 29alex 30[root@manager ~]# echo $2 31[root@manager ~]# 32 33

三剑客

sed

sed执行流程

在这里插入图片描述

sed N

1[root@manager ~]# sed 'N;s#\n# #g' num.txt 21 2 33 4 45 6 57 8 69 10 7[root@manager ~]# sed 'N;N;N;N;N;N;N;N;s#\n# #g' 8num.txt 91 2 3 4 5 6 7 8 9 1010 11[root@manager ~]# sed 'N;N;N;N;N;N;N;N;N;s#\n# #g' 12num.txt 131 2 3 4 5 6 7 8 9 10 14#使用sed命令的中循环 15#sed标签功能 16[root@manager ~]# sed ':label ;N;s#\n# #g;t label' 17num.txt 181 2 3 4 5 6 7 8 9 10 19[root@manager ~]# tr '\n' ' ' <num.txt 201 2 3 4 5 6 7 8 9 10 [root@manager ~]# 21[root@manager ~]# xargs <num.txt 221 2 3 4 5 6 7 8 9 10 23[root@manager ~]# awk -vORS=" " '1' num.txt 241 2 3 4 5 6 7 8 9 10 [root@manager ~]# 25 26

sed功能

sed:功能:
增删改查
p(查) print
-n ‘3p’
-n ‘1,3p’
-n ‘/oldboy/p’
过滤日志: 时间范围 -n ‘/开始/,/结束/p’ access.log
d(删除) delete
cai (cia) c( replace 替换这一行的内容) a(append) i(insert)
s(替换) sub substitute
补充符号:
&

1[root@manager ~]# seq 5 |sed '3c oldboyedu.com ' 21 32 4oldboyedu.com 54 65 7[root@manager ~]# seq 5 |sed '3a oldboyedu.com ' 81 92 103 11oldboyedu.com 124 135 14[root@manager ~]# seq 5 |sed '3i oldboyedu.com ' 151 162 17oldboyedu.com 183 194 205 21 22

#&

1[root@manager ~]# echo {1..20} |sed -r 's#[0-9]+# 2<&>#g' 3<1> <2> <3> <4> <5> <6> <7> <8> <9> <10> <11> <12> 4<13> <14> <15> <16> <17> <18> <19> <20> 5[root@manager ~]# echo {1..20} |sed -r 's#[0-9]+# 6<&>#g' 7 8

正则表达式

正则vs通配符

在这里插入图片描述

正则

在这里插入图片描述在这里插入图片描述
man perlretut

1#取出 id:右边的数字 2echo 'id:1 id:999 id:12306 id:996 oldboy666 3alex777 12580' >id.txt 4[root@manager ~]# #取 xxxx右边/左边 的内容 5[root@manager ~]# #取出的位置 6[root@manager ~]# ##perl正则 零宽断言 lookaround 7[root@manager ~]# ###lookahead 匹配左边 8[root@manager ~]# ###lookbehind 批量右边 9[root@manager ~]# echo 'by oldboy linux' |grep -P '(? 10<=old)boy' 11by oldboy linux 12[root@manager ~]# echo 'by oldboy linux' |grep -Po 13'(?<=old)boy' 14boy 15[root@manager ~]# ip a s eth0 162: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 17qdisc pfifo_fast state UP group default qlen 1000 18link/ether 00:0c:29:d9:30:f5 brd ff:ff:ff:ff:ff:ff 19inet 10.0.0.61/24 brd 10.0.0.255 scope global 20noprefixroute eth0 21valid_lft forever preferred_lft forever 22inet6 fe80::a6c9:6aee:108b:2757/64 scope link 23noprefixroute 24valid_lft forever preferred_lft forever 25[root@manager ~]# ip a s eth0 |grep -Po '[0-9.]+(?=/24)' 2610.0.0.61 27[root@m01 ~]# ip a s eth0 |grep -Po '(?<=inet )[0-9.]+' 2810.0.0.61 29 30

在这里插入图片描述
在这里插入图片描述

awk

内容

awk格式
awk执行过程


内置变量
awk条件
比较表达式
正则
特殊 BEGIN和END
范围
if fork
awk数组
awk数组分析日志


格式与参数

awk 参数 ‘条件{动作}’ 文件 …

-F 指定分隔符 -v 创建或修改awk变量 1次只能创建或修改1个变量

shell脚本中的变量 传递到awk中

1[root@manager ~]# x=1 2[root@manager ~]# y=21 3[root@manager ~]# awk -vn1=1 -vn2=21 'BEGIN{print 4n1/n2}' 50.047619 6[root@manager ~]# awk -vn1=$x -vn2=$y 'BEGIN{print 7n1/n2}' 80.047619 9 10

awk完整的执行过程

awk执行过程

11 读取文件内容之前执行awk命令行参数 -F或 -v执行BEGIN{}模块 22 正在读取文件读取文件的1行判断这一行是否满足条件满足 执行对应的动作不满足 读取下一行 直到文件结尾 33 读取文件后执行END{}里面的内容 4 5

在这里插入图片描述

行与列

行 record 记录 行 列 field 字段 域 列

#取出第1行

1[root@m01 ~]# awk 'NR==1' /etc/passwd 2root:x:0:0:root:/root:/bin/bash 3 4

#取多行 取出 从第5行到最后1行

1awk 'NR>=5' /etc/passwd 2 3

#取出2-5行的内容

1[root@m01 ~]# awk 'NR>=2 && NR<=5' /etc/passwd 2bin:x:1:1:bin:/bin:/sbin/nologin 3daemon:x:2:2:daemon:/sbin:/sbin/nologin 4adm:x:3:4:adm:/var/adm:/sbin/nologin 5lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6 7

#过滤

1[root@m01 ~]# awk '/oldboy/' /etc/passwd 2oldboy01:x:1000:1000::/home/oldboy01:/bin/bash 3oldboy02:x:1001:1001::/home/oldboy02:/bin/bash 4oldboy03:x:1002:1002::/home/oldboy03:/bin/bash 5oldboy04:x:1003:1003::/home/oldboy04:/bin/bash 6oldboy05:x:1004:1004::/home/oldboy05:/bin/bash 7oldboy06:x:1005:1005::/home/oldboy06:/bin/bash 8oldboy07:x:1006:1006::/home/oldboy07:/bin/bash 9oldboy08:x:1007:1007::/home/oldboy08:/bin/bash 10oldboy09:x:1008:1008::/home/oldboy09:/bin/bash 11oldboy10:x:1009:1009::/home/oldboy10:/bin/bash 12 13

#扩展
##awk只写条件 条件满足后 默认执行 {print $0}显示这一行的内容

1[root@m01 ~]# awk '/oldboy/{print $0}' /etc/passwd 2oldboy01:x:1000:1000::/home/oldboy01:/bin/bash 3oldboy02:x:1001:1001::/home/oldboy02:/bin/bash 4oldboy03:x:1002:1002::/home/oldboy03:/bin/bash 5oldboy04:x:1003:1003::/home/oldboy04:/bin/bash 6oldboy05:x:1004:1004::/home/oldboy05:/bin/bash 7oldboy06:x:1005:1005::/home/oldboy06:/bin/bash 8oldboy07:x:1006:1006::/home/oldboy07:/bin/bash 9oldboy08:x:1007:1007::/home/oldboy08:/bin/bash 10oldboy09:x:1008:1008::/home/oldboy09:/bin/bash 11oldboy10:x:1009:1009::/home/oldboy10:/bin/bash 12 13

#RS 每一行结束标记 默认是回车

1[root@m01 ~]# awk -vRS='/' '{print NR,$0}' /etc/passwd 2 3

1[root@m01 ~]# seq 10|awk -vORS=' ' '{print $0}' 21 2 3 4 5 6 7 8 9 10 [root@m01 ~]# 3# 创建行分隔符 4 5

1[root@manager ~]# awk -F: '{print $1,$3}' /etc/passwd 2 3

#调换 /etc/passwd 第1列和最后一行 内容

1[root@m01 ~]# sed -r 's#(^.*)(:x.*:)(.*)#\3\2\1#g' /etc/passwd 2 3[root@m01 ~]# awk -F: -vOFS=: '{print $NF,$2,$3,$4,$5,$6,$1}' /etc/passwd 4 5[root@m01 ~]# awk -F: -vOFS=: '{tmp=$1;$1=$NF;$NF=tmp;print }' /etc/passwd 6 7

内置变量

NR Number of Record 记录号 行号 RS Record Separator 记录分隔符 记录着每一行的结束标记支持正则 ORS Output Record Separator awk显示每一行的时候 每一行之间的分隔符


$0 表示一整行的内容 FS -F: === -vFS=: Field Separator 字段分隔符 菜刀 OFS Output Field Separator 输出字段分隔符 输出每一列的时候 每一列之间分隔符 默认是空格 OFS内容 相当于是 ,的内容 NF Number of Field 每一行有多少列


awk条件

比较表达式
正则
BEGIN{} 和END{}
范围

比较

#取行

1[root@manager ~]# awk 'NR>=5' /etc/passwd 2 3

#取出/etc/passwd 中第3列 大于0并且小于1000的行

1[root@m01 ~]# awk -F: '$3>0 && $3<1000' /etc/passwd 2 3

#取出磁盘使用率高于20%的名字

1[root@m01 ~]# df -h|awk -F'[ %]+' 'NR>1 && $5>2 {print $1,$5}' 2/dev/sda1 3 3 4

#小坑预警:
##通过awk进行比较 如果某一列中有符号 awk会认为是字符串的对比 字符串的对比先比较第1位

1[root@m01 ~]# df -h|awk -F'[ ]+' 'NR>1 && $5>20 {print $1,$5}' 2/dev/sda1 3% 3 4

正则

~ 匹配 $3 ~ /^[01]/ !~ 不匹配 排除 $3 !~ /^[01]/

# ^ 行开头 某一列的开头
# $ 行结尾 某一列的结尾


#取出 /etc/passwd中第3列 以数字1或0开头的行

1[root@manager ~]# awk -F: '$3 ~ /^[01]/' /etc/passwd 2 3

#统计 access.log中 请求是.jpg或 .gif结尾的图 流量总和
##类型 $7
##流量 $10
##条件 : 找出第7列以.jpg或.gif结尾的 $7 ~ /.jpg$|.gif$/
##{动作}: {sum=sum+$10}

1[root@m01 ~]# awk '$7~/.jpg$|.gif$/ {sum=sum+$10}END{print sum/1024^2}' access.log 290.7682 3 4
1[root@m01 ~]# awk ' {sum=sum+$10}END{print sum/1024^2}' access.log 22363.68 3 4

BEGIN{} vs END{}

BEGIN{} BEGIN里面的内容会在awk读取文件之前 运行

  1. 用来进行测试 与计算2.BEGIN定义 awk内置变量3.显示某列的时候 提前显示的标题

END{} END里面的内容 会在awk读取完文件后运行

  1. 先进行计算 最后在END{}输出结果
1[root@manager ~]# #awk -F: '$3 ~ /^[01]/' /etc/passwd 2[root@manager ~]# #awk -vFS=: '$3 ~ /^[01]/' /etc/passwd 3[root@manager ~]# #awk 'BEGIN{FS=":"}$3 ~ /^[01]/' /etc/passwd 4[root@manager ~]# awk -F: 'BEGIN{print "用户名","UID"}{print $1,$3}' /etc/passwd |column -t 5 6

范围

1[root@m01 ~]# awk 'NR==1,NR==5' /etc/passwd 2root:x:0:0:root:/root:/bin/bash 3bin:x:1:1:bin:/bin:/sbin/nologin 4daemon:x:2:2:daemon:/sbin:/sbin/nologin 5adm:x:3:4:adm:/var/adm:/sbin/nologin 6lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 7 8
1[root@manager ~]# awk '/root/,/nobody/' /etc/passwd 2 3
1[root@m01 ~]# awk -F: '$3==0,$3==5' /etc/passwd 2root:x:0:0:root:/root:/bin/bash 3bin:x:1:1:bin:/bin:/sbin/nologin 4daemon:x:2:2:daemon:/sbin:/sbin/nologin 5adm:x:3:4:adm:/var/adm:/sbin/nologin 6lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 7sync:x:5:0:sync:/sbin:/bin/sync 8 9
1[root@m01 ~]# awk '$1~/root/,$1~/nobody/' /etc/passwd 2root:x:0:0:root:/root:/bin/bash 3bin:x:1:1:bin:/bin:/sbin/nologin 4daemon:x:2:2:daemon:/sbin:/sbin/nologin 5adm:x:3:4:adm:/var/adm:/sbin/nologin 6lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 7sync:x:5:0:sync:/sbin:/bin/sync 8shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown 9halt:x:7:0:halt:/sbin:/sbin/halt 10mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 11operator:x:11:0:operator:/root:/sbin/nologin 12games:x:12:100:games:/usr/games:/sbin/nologin 13ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin 14nobody:x:99:99:Nobody:/:/sbin/nologin 15 16

awk条件小结

比较表达式 通过awk内置变量使用 NR>5 $3>=10 正则 配置某一列中 包含/不包含xxxx 日志过滤$3~/^[01]/ BEGIN{} 和END{} END{}输出最后的结果;BEGIN{}计算 范围 过滤时间 /2015:11:02/,/2015:11:59/


if

#单分支 条件

1if(条件) 2 print 3 4
1[root@manager ~]# awk 'NR==3' /etc/passwd 2daemon:x:2:2:daemon:/sbin:/sbin/nologin 3[root@manager ~]# awk '{if(NR==3) print $0}' /etc/passwd 4daemon:x:2:2:daemon:/sbin:/sbin/nologin 5 6

#双分支

1if(条件) 2 print 3else 4 print 5 6

#企业面试题:请过滤range.log中在device: {}里面出现了多少次oldboy,过滤并统计出来
环境

1[root@m01 ~]# cat range.log 2oldboy is a linuxer. 3device: { 4 oo 5 oldboy 6 no sql 7 this is log 8 niu niu 9} 10oldboy 11device: { 12 oldboy 13 no sql 14 this is log 15 niu niu 16} 17oldboy 18device: { 19 oldboy 20 no sql 21 this is log 22 niu niu 23} 24device: { 25 oldboy 26 no sql 27 this is log 28 niu niu 29 } 30 31
1[root@m01 ~]# awk '/{/,/}/{if(/oldboy/) i++}END{print i}' range.log 24 3 4
1awk ' 2/{/ , /}/{ #条件 匹配 {} 里面的内容 3 if(/oldboy/) #二次过滤 找出{}中 并且 还是oldboy的 4 i++ #计数 5 } 6 END{ 7 print i #显示结果 8 }' range.log 9 10

for循环

c语言形式
专门用来给awk数组 循环

for((i=1;i<=10;i++));do echo $i; done for(i=1;i<=10;i++) print i

#显示 1…10 seq 10

1[root@m01 ~]# awk 'BEGIN{for(i=1;i<=10;i++) print i }' 21 32 43 54 65 76 87 98 109 1110 12 13

#计算 1+2+3…+10

1[root@m01 ~]# awk 'BEGIN{for(i=1;i<=10;i++) sum+=i ;print sum }' 255 3 4
1[root@m01 ~]# awk 'BEGIN{for(i=1;i<=10;i++) {sum+=i ;print sum} }' 21 33 46 510 615 721 828 936 1045 1155 12 13

#for配合NF
环境

1cat chengji.txt 2waiwai 90 98 98 96 96 92 3xiaoyu 70 77 85 83 70 89 4gege 85 92 78 94 88 91 5xingxing 89 90 85 94 90 95 6bingbing 84 88 80 92 84 82 7dandan 64 80 60 60 61 62 8 9

#显示出姓名及每个人的平均数

1[root@manager ~]# awk '{sum=$2+$3+$4+$5+$6+$7;print 2