续上篇。
字符串截取
1)
${变量名:起始位置:结束位置} #位数从0开始计算
a=abcdefg
从0开始数 0123456
echo ${a::3} #从0开始到第三位截取可以省略0不用写
2)
echo ${#a} #计算有多少位数ech
expr substr "$变量名" 起始位置 长度 #从1开始数
3)
echo $a | cut -b 1-7(指定范围) 位数从1开始计算
echo $a | cut -b -7 #第一位到第七位
echo $a | cut -b 2- #第二位到最后
echo $a | cut -b 2,4 #第2和4位
echo $a | cut -b 6 #只要第六位
x=$[RANDOM%7+1] #创建随机数,范围1-7
x=$[RANDOM%8] #创建随机数,范围0-7
----------------------------------------------------------------------------------------
编写8位随机字符串
#!/bin/bash
a=qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789
#定义随机玛为所有字母数字
for i in {1..8}
do
n=$[RANDOM%62]
#定义随机数控制在0-61之间
p=${a:n:1}
#截取a里(随机数)位字符,长度1位
p1=$p1$p
#p1为总和字符串数=自身字符+随机a里的数(8次共8个)
done
echo $p1
#输出结果
-----------------------------------------------------------------------------------------------------------
字符替换
echo ${变量名/第一个要替换的字符串/替换成**}
对变量本身没有改变
echo ${a//b/pp} # “//”为替换所有b为pp
echo ${a/b/} #替换的东西为空则不显示
掐头去尾
a=root:x:0:0:root:/root:/bin/bash
从左到右删除(掐头)
echo ${a#root} #从左到右删除变量a内第一个的root关键词字符
echo ${a#*:} #删除第一个:前的所有
echo ${a##*:} #删除:前的所有
从右到左删除(去尾)
echo ${a%bash} #从右到左删除a内的第一个bash关键词
echo ${a%%:*} #删除:后面的所有
${a:-初值} #定义初值
*------------------------------------------------------------------------------------------------------------------
expect预期交互
提前安装expect包
#!/bin/bash
expect << EOF #使用Expect工具
spawn ssh -o StrictHostKeyChecking=no 172.25.0.10 #执行远程连接任务
expect "password:" { send "redhat\r" } #当看到password时输入密码并回车
expect "#" { send "touch /tmp.txt\r" } #当看到#号时,输入创建文件
expect "#" { send "exit\r" } #默认最后一条不执行,执行以上完了自动退出
EOF #任务结束
ssh -o StrictHostKeyChecking=no server0 #默认输出no不出现yes/no提示
/root/.ssh/known_hosts #里面记录ssh记录,建议rm
基本正规则
配合grep使用
^a -----------匹配行首 a$ -----------匹配行尾 [ ab] --------集合,匹配集合中的任意单个字符 [ ^ab ] ------对集合取反 . ----------------任意单个字符 * ----------------匹配前一个字符任意次数[*不允许单独使用] \{n,m\} -------匹配前一个字符n到m次 \{n\} --------匹配前一个字符n次 \{n,\} --------匹配前一个字符n次以上 \( \ ) ---------------保留 扩展正则 + ----------------------匹配前面一个字符最少匹配一次,可以有多次 ? ----------------------匹配前面一个字符最多匹配一次 {n,m} ---------匹配前面一个字符n到m次 () --------------------组合为整体,保留 | ---------------------或者 \b -----------单词边界 |
grep 不支持扩展正则 加-E选项和egrep效果一样
egrep 支持扩展
egrep "ro+" /etc/passwd 匹配ro开头的且o出现多次或一次的行
egrep "ro?" /etc/passwd 匹配ro开头的且o最多出现一次/可以出现0次的行
egrep "ro{1,5}"/etc/passwd 匹配ro开头且o出现1到5次的行
egrep "ro|sh" /etc/passwd 匹配ro或sh的行
egrep "\broot\b" /etc/passwd 匹配root单独存在的行与其他字符隔开的
egrep "\broot" /etc/passwd 匹配root左边没有字符串的行
sed -r "s/^(.)(*)(.)$/\3\2\1/" /etc/passwd
每行分为3部分(第一个/中间部分/最后一个)顺序\1\2\3
sed 流式编辑器
非交互式,逐行处理,结果输出屏幕上
用法:
默认sed会将所有输出的内容都打印出来,可以使用-n屏蔽默认输出(默认每行多输出一行)
sed [选项] ‘编辑指令([定址符]处理动作)’ 文件.. ..
前置命令 | sed [选项] '编辑指令'
- -n 屏蔽默认输出
- -i 直接修改文档
- -r 支持扩展正则
sed 'p' /etc/passwd #显示所有行,默认每行多输出一次
sed '1p' /etc/passwd #显示所有行,第一行显示2行
sed -n '1p' /etc/passwd #显示第一行
sed -n '1p;5p' /etc/passwd #显示1和5行,
sed -n '1,5p' /etc/passwd #显示1到5行,
sed -n '1~2p' /etc/passwd #打印奇数行(1,3,5,7..行)
#'n~m' 第n行开始打印每隔(m-1)行打印,隔的那m-1行不打印
sed -n '2~2p' /etc/passwd #打印偶数行(2,4,6,8..行)
sed -n '2,+2p' /etc/passwd #打印第二行以及后面的2行
基本正则表达式
sed -n '/root/p' /etc/passwd #搜索包含root的行
sed -n '/^root/p' /etc/passwd #搜索以root开头的行
sed -n '/bash$/p' /etc/passwd #搜索以bash结尾的行
sed -n '/ro\{1,\}/p' /etc/passwd #搜索以ro开头的行且o出现1次以上的行包括1次
-r 和扩展正则表达式使用
sed -n -r '/ro{1,}/p' /etc/passwd
#搜索以ro开头的行且o出现1次以上的行包括1次
sed -n -r '/^root{1,}/p' /etc/passwd
#
sed -n -r '/root${1,}/p' /etc/passwd
sed -n '$=' /etc/passqwd #"="行号,$=最后一个行号,(总行数)
-i 直接修改文件内容
sed -i '1,4d' a.txt #永久删除1到4行
sed -i 's/[0-9]//g' a.txt #所有数字替换空格(不显示)
sed -i '1p;5p' a.txt #第1和5行多打印一行
sed -i -n '1p;5p' a.txt #直接显示第1和5行,其他行屏蔽(删掉)
- a:在指定的行之后追加文本 (增)
- d 删除 (删)
- s替换“s/旧/新/g”(改)
- p打印显示 (查)
- c:替换指定的行
- i: 在指定的行之前插入文本
sed 'i 666' a.txt #在每行前插入666独立的一行
666
chihiro:x:1007:1007::/home/chihiro:/bin/bash
sed '1a 666' a.txt 在第1行前追加666独立的一行
sed '$a 666' a.txt 在尾行追加一行666
sed 'c 666' a.txt 逐行处理(每行)替换全部(内容)为666
sed ‘2c 666’ a.txt 第二行替换为666
r读
w写
sed 'r 1.txt' a.txt 将1.txt里的内容读进a.txt的每行后面
sed 'w 2.txt' 1.txt 将1.txt里的内容覆盖到2.txt(文件不存在则自动创建)与r格式位置相反
awk 工具
awk 查看文本内容,
常用单引号,双引号用于变量
awk [选项] '[条件]{指令}' 文件
print
awk '{print }' 1.txt 查看文件内所有内容
awk '{print $1}' 1.txt 查看文件第一列(默认以空格/tab位识别列数)
-F可指定分隔符 或-F[:/] 表示两个符号都是分隔符,不加[ ]则为一个分隔符(:/)
awk -F: '{print $1,$7}' /etc/passwd
root /bin/bash
...
mysql /sbin/nologin
#指定:号为分隔列数,打印所有行的第1和7的列字符
root(1):x(2):0(3):0(4):root(5):/root(6):/bin/bash(7)
awk -F/ '{print $1,$4}' /etc/passwd
root:x:0:0:root: bash
...
mysql:x:27:27:MariaDB Server: mysql:
awk -F[:/] '{print $7}' /etc/passwd
root(1):x(2):0(3):0(4):root(5):(6)/root(7):(8)/bin/(9)bash(10)
#以:和/为分隔符,查找第七列,:/之间判为空格为一列
df -h | awk '{print $4}' 打印磁盘的剩余空间
内置变量
- $0 文本当前行的全部内容
- $1 文本的第1列
- $2 文件的第2列
- $3 文件的第3列,依此类推
- NR 文件当前行的行号
- NF 文件当前行的列数(有几列)
awk -F: '{print NR或NF}' /etc/passwd 显示(以:分隔的)总行数/每行总列数
awk '{print $1 "666"} 1.txt 所有第1列显示并加常量“666”(常量引号引起来)
ifconfig eth0
RX接收
TX发送
ifconfig eth0 | awk '/TX p/{print $5}'
网卡信息的接收信息第5列(字节)
ifconfig eth0 | awk '/RX p/{print $5}'
网卡发送信息第五列(字节)
df -h | awk '/\/$/{print $4}'
第4列根分区磁盘剩余空间大小(/$是以/结尾的行)
awk '/Failed/{print $11}' /var/log/secure
Apr 13 14:07:16 localhost sshd[5894]: Failed password for root from 172.25.0.10 port 35880 ssh2
过滤远程连接密码失败的ip地址
awk处理的时机
awk [选项] '[条件]{指令}' 文件
awk [选项] ' BEGIN{指令} {指令} END{指令}' 文件
- BEGIN{ } 行前处理,读取文件内容前执行,指令执行1次
- { } 逐行处理,读取文件过程中执行,指令执行n次
- END{ } 行后处理,读取文件结束后执行,指令执行1次
awk 'BEGIN{A=20;print A+3.3}'#读取文件前处理内容(计算20+3.3)
awk 'BEGIN{x=8;x--;print x}' #读取文件前执行8-1(--为-1)结果输出
awk 'BEGIN{A=5;print A*3.2}{print $1}END{print "下班"}' 1.txt
#执行任务前的任务先执行一个小任务(A*3.2)再执行主任务最后执行小任务(输出下班)
awk -F: 'BEGIN{}{}END{}' /etc/passwd
awk -F: 'BEGIN{print "User\tUID\tHome"}{print $1"\t"$3"\t" $6}END{print "Total",NR,"lines"}' /etc/passwd
#先打印User\tUID\tHome(\t表示tab键自动补适合长度空格),然后执行任务第1/3/6列的内容并中间\t空格,最后处理输出"Total",NR,"lines"(,表示空格、NR行数)
awk -F: '/bash$/{print}' /etc/passwd
#以bash结尾的所有行
awk -F: '/root/' /etc/passwd
#包含root的所有行
awk -F: '/^(root|adm)/{print $1,$3}' /etc/passwd
#以root或adm开头的行中第1,3列
awk -F: '$1~/root/' /etc/passwd
#第一列包含root的所有行(~表示包含)
awk -F: '$7!~/nologin$/{print $1,$7}' /etc/passwd
#第7列结尾包不含nologin的所有行中的第第1和7列的内容(!~反向匹配)
UID1000内为系统账户
数值/字符串比较设置条件
比较符号:==(等于) !=(不等于) >(大于)
>=(大于等于) <(小于) <=(小于等于)
awk -F: 'NR==3{print}' /etc/passwd
#行号=3的内容输出屏幕 {print} 可省略
awk -F: '$3>=1000{print $1,$3}' /etc/passwd
#第3列大于等于1000的行中的第第1和3列内容/注:一个=为替换
awk -F: '$3<10{print $1,$3}' /etc/passwd
#第3列小于10的所有行中第1和第3列内容输出屏幕
awk -F: '$1=="root"' /etc/passwd
#所有第1列中为root的行
awk -F: '$3>10 && $3<20' /etc/passwd
#所有第3列中大于10的且(&&)小于20的行
awk -F: '$3>10 && $3<20{print $1,$3}' /etc/passwd#匹配到的第3列中第1/3列
awk -F: '$3>1000 || $3<10' /etc/passwd
#第3列大于1000或者小于10的(都匹配)所有行
seq 200 | awk '$1%3==0' //找200以内3的倍数(取3的余数0)
逻辑思维清析(<10且>20不存在)
&& 并且
| | 或者
- 数组名[下标]
a=(11 22 33 44 55) #(定义多个值)定义数组名以及内容
a=(第0个 1 2 3 4..)位置从0开始排序
echo $a ---11 #默认输出第0个
echo ${a[@]} #列出数组a包含的值
echo ${a[3]} #中括号内的3表示调用数组的第4个值
awk 综合脚本
#!/bin/bash
u=`awk -F: '/bash$/{print $1}' /etc/passwd`
先定义u=bash结尾的用户名
for i in $u
do
grep ^$i: /etc/shadow | awk -F: '{print $1" ---> "$2}' 先查找变量i存在的行再给awk执行
#awk -F: '/^$i:/{print $1" --> "$2}' /etc/shadow
这样写awk无法识别$i是第几列,而不会认为他是上面的变量
#awk -F: '/'^$i:'/{print $1" --> "$2}' /etc/shadow
单引引起来使变量生效
done
awk '{a[$1]++}END{for(i in a){print i,a[i]}}' ip.txt
先执行逐行任务 定义"数组名[下标]值"(逐行处理定义值,每个下标原值为0,出现一次+1),逐行完后最终处理for循环a(数组名内的通过逐行处理出来的所有下标)赋予i。打印下标,值(数组名[下标]=值)
awk '{a[$1]++}END{for(i in a){print i,a[i]}}' /var/log/httpd/access_log
sort 排序(-r表示反序)(-n表示按数字顺序升序排列)(-k指定按第几个字段来排序)
sort -r a.txt -k 2
---------------------------------------------------------------------------------------------------------------------
Nginx默认安装路径为/usr/local/nginx,该目录下会提供4个子目录,分别如下:
/usr/local/nginx/conf 配置文件目录
/usr/local/nginx/html 网站页面目录
/usr/local/nginx/logs Nginx日志目录
/usr/local/nginx/sbin 主程序目录
#!/bin/bash
y=`yum repolist | awk '/repolist/{print $2}' | sed "s/,//"`
[ $y -eq 0 ] && exit
检测yum是否可用
yum -y install gcc openssl-devel pcre-devel
tar -xf /root/nginx-1.12.2.tar.gz
cd nginx-1.12.2
./configure
make
make install
源码编译安装
bash -x 脚本名 #检测脚本书写 是否错误
#!/bin/bash
while :
do
uptime | awk '{print "当前CPU的平均负债:" $8,$9,$10}'
ifconfig eth0 | awk '/RX p/{print "当前eth0网卡接收流量为:"$5"字节"}'
ifconfig eth0 | awk '/TX p/{print "当前eth0网卡发送流量为:"$5"字节"}'
free -m | awk '/^Mem/{print "内存剩余空间:"$4"M"}'
df -h | awk '/\/$/{print "磁盘剩余空间:"$4}'
u=`cat -n /etc/passwd | wc -l`
echo "计算机账户数量是: $u"
s=`who | wc -l`
echo "当前登录账户数量是: $s"
ps=`ps aux |wc -l`
echo "计算机当前开启的进程数量是: $ps"
r=`rpm -qa | wc -l`
echo "当前计算机已安装软件包数量为: $r"
echo "----------------------------------------"
sleep 5
clear #清屏
done
-------------------------------------------------------------------------------------------------------
netstat 查看系统中启动的端口信息
-n以数字格式显示端口号
-t显示TCP连接的端口
-u显示UDP连接的端口
-l显示服务正在监听的端口信息,如httpd启动后,会一直监听80端口
-p显示监听端口的服务名称是什么(也就是程序名称)
/usr/local/nginx/sbin/nginx //启动服务
/usr/local/nginx/sbin/nginx -s stop //关闭服务
/usr/local/nginx/sbin/nginx -V //查看软件信息
netstat -ntulp | grep -q 80 #-q不显示结果配echo $?使用
#!/bin/bash
read -p "start、stop、restart还是status:" r
case $r in
start)
/usr/local/nginx/sbin/nginx;;
stop)
/usr/local/nginx/sbin/nginx -s stop;;
restart)
/usr/local/nginx/sbin/nginx -s stop
/usr/local/nginx/sbin/nginx;;
status)
netstat -nutlp | grep -q nginx
if [ $? -eq 0 ];then
echo "服务已启用"
else
echo "服务未启用"
fi;;
*)
echo Error;;
esac
---------------------------------------------------------------------------------------------------------------
#!/bin/bash
awk '/Failed pass/{print $11}' /var/log/secure | awk '{ip[$1]++}END{for(i in ip){print ip[i],i}}' | awk '$1>3{print $2}'
awk '/Invalib user/{print $10}' /var/log/secure | awk '{ip[$1]++}END{for(i in ip){print ip[i],i}}' | awk '$1>3{peinr $2}'