一、shell基础
1、利用shell脚本安装nginx
[root@zhu shell]# vim install_nginx.sh #!/bin/bash yum -y install gcc gcc-c++ make pcre-devel openssl-devel wget tar -zxvf nginx-1.22.1.tar.gz -C /usr/local/src cd /usr/local/src/nginx-1.22.1 ./configure --prefix=/usr/local/nginx make -j 4 make install [root@zhu shell]# sh install_nginx.sh
二、变量
1、变量类型
环境变量
位置变量
预定义变量
自定义变量
(1)自定义变量:(用户自主设置)
定义变量:以固定的名称,存放可能有变化的值
变量不指定类型但是可以接受任意类型数据的赋值
定义变量的格式:变量名=变量值
变量名:临时存放数据的地方
变量值:临时可变化的数据
注意:=两边不能出现空格
变量名去过已经存在则覆盖之前的变量值
变量名规范;不能以数字开头、由字母/数字/下划线组成,不能包含特殊字符(# + ?)
查看变量:
查看变量的语法格式:
Echo $变量名(可以同时查看多个变量)
Echo ${变量名}(不加{}的查看变量形式有可能出现歧义(会识别出未定义的变量名))
(。为特殊符号,后面的内容不属于变量名——正常引用变量名)
Rendonly 变量名:只读变量
删除格式: Unset 变量名 ——只是把变量的值赋值为空
Echo +选项 (-n:不换行;默认换行)
-e:支持扩展形式,转义字符 ——默认直接输出不显示只能进行转移
\t:制表符空格 \n:换行
(2)环境变量
由系统管理 变量名都是大写
env可以查看环境变量
命令搜索路径变量
返回当前的工作目录
返回当前登录的用户名
返回当前登录用户的(编号)UID
返回当前用户家目录
返回当前命令解释器
(3)位置变量
bash内置的变量,存储脚本执行时的参数
使用$n,n是数字 如果n=>10需要在数字两边加上{}
(按顺序接受值,多的参数也不会打印输出)
修改脚本内容
#!/bin/bash
echo $2
echo $1
echo $3
(参数和$后面的数字按顺序绑定)
修改脚本内容
#!/bin/bash
echo $2
echo $1
echo $3
echo $8
(必须要让$n和参数个数对应才能接收到参数值)
(先检测到$后面的1就是n——识别成了$1值为11,再和后面的0组合成110)
(在数字两边加上{}会识别成一个整体就不会出现混淆的情况)
(4)预定义变量
bash的内置变量,只能调用不能修改。
(非0表示上次任务执行失败)
[root@localhost day01]# cat a.sh #!/bin/bash echo $0 //当前执行的脚本名 echo $$ //当前脚本的进程号 echo $# //当前位置参数的个数(已加载的位置变量的个数) echo $* //当前位置参数的所有值(所有位置变量的值) [root@localhost day01]# chmod +x a.sh [root@localhost day01]# ./a.sh a b c d ./a.sh 9906 4 a b c d
三、判断语句
1、条件判断
语法格式:
Test选项 参数
[选项 参数](一般用[])
(1)字符串测试:
基本语法:
是否为空[ -z 字符串 ]
等于[ 字符串1 == 字符串2 ]
不等于[字符串1 != 字符串2 ]
[root@localhost ~]# echo $TT [root@localhost ~]# [ -z $TT ] [root@localhost ~]# echo $? 0 [root@localhost ~]# TT="hello" [root@localhost ~]# [ -z $TT] -bash: [: 缺少 `]' [root@localhost ~]# [ -z $TT ] //两边需要空格 [root@localhost ~]# echo $? 1 [root@localhost ~]# [root@localhost ~]# [ a==a ] [root@localhost ~]# [a==a] bash: a: 未找到命令... [root@localhost ~]# [ a==a ] [root@localhost ~]# [ a == a ] [root@localhost ~]# [a != a] bash: [a: 未找到命令... [root@localhost ~]# [ a != a ] [root@localhost ~]# echo $? //上一次命令收否正确(正确为0,错误为1) 1
(2)整数值的比较
基本语法:
[整数值1 操作符 整数值2]
[root@localhost ~]# [ 3 -lt 8 ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ 3 -gt 2 ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ 3 -eq 2 ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ 3 -le 2 ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ 3 -ge 2 ]
[root@localhost ~]# echo $?
0
(3)常量和变量的比较
判断计算机登录用户的个数是否大于等于2 [root@localhost ~]# who | wc -l 2 [root@localhost ~]# [ $(who | wc -l) -ge 2 ] [root@localhost ~]# echo $? 0
2、文件状态测试
语法格式:
[操作符 文件/目录]
判断是否存在 [root@localhost ~]# [ -e /etc ] [root@localhost ~]# echo $? 0 [root@localhost ~]# [ -e /etc/iar ] [root@localhost ~]# echo $? 1
判断是否为目录
[root@localhost ~]# echo $?
0
判断是否为文件 [root@localhost ~]# [ -f /etc ] [root@localhost ~]# echo $? 1 [root@localhost ~]# [ -f /etc/hosts ] [root@localhost ~]# echo $? 0
判断是否可读 [root@localhost ~]# [ -r /etc/hosts ] [root@localhost ~]# echo $? 0
判断是否为可写 [root@localhost ~]# [ -w /etc/hosts ] [root@localhost ~]# echo $? 0
判断是否为执行 [root@localhost ~]# [ -x /etc/hosts ] [root@localhost ~]# echo $? 1
3、判断语句
(1)if语句----对范围做判断
1)if单分支判断---一个选择可能有结果可能没有结果
当“条件成立”时执行命令序列;否则,不执行任何操作。
案例 判断用户名与密码是否为空 [root@localhost day02]# vim if1.sh #!/bin/bash read money read price if [ $money -ge $price ];then echo "不差钱!随便买!!!" fi echo "家里失火了。。跑。。" [root@svr7 ~]# cd /root/shell/day02 [root@svr7 day02]# vim user_v1.sh [root@localhost day02]# sh if1.sh 1000 1999 家里失火了。。跑。。 [root@localhost day02]# sh if1.sh 1000 999 不差钱!随便买!!! 家里失火了。。跑。。
2)if双分支判断---一个选择但是一定要有结果
当“条件成立”时执行命令序列1;否则,执行命令序列2。
应用案例 求两个整数最大值 [root@localhost day02]# vim if2.sh #!/bin/bash #读取两个整数求出最大值 read m read n if [ $m -gt $n ];then echo $m else echo $n fi [root@localhost day02]# sh if2.sh 2 3 3
3)if多分支判断---提供多种选择但是只有一个结果
相当于if语句嵌套;if双分支判断语法;针对多个条件分别执行不同的操作
[root@localhost day02]# vim if3.sh #!/bin/bash #根据输入的星星数返回对应的段位 read -p "输入星星数:" xing if [ $xing -ge 0 ]&&[ $xing -lt 5 ];then echo "黑铁!!!" elif [ $xing -ge 5 ]&&[ $xing -lt 10 ];then echo "青铜!!" elif [ $xing -ge 10 ]&&[ $xing -lt 20 ];then echo "铂金" elif [ $xing -ge 100 ];then echo "嘴强王者" else echo "请重新输入" fi [root@localhost day02]# sh if3.sh 输入星星数:100 嘴强王者
(2)case语句---把多个值当做选项来做判断
检查、判断变量的取值
效果类似于多分支的if语句
如果与预设的值相匹配,则执行对应的操作
命令序列最后必须以分号结尾
[root@localhost day02]# vim case.sh #!/bin/bash #实现客户过程 echo "查询话费请按1" echo "查询流量请按2" echo "办理流量套餐请按3" echo "办理宽带业务请求按4" echo "转接人工客服请按0" #输入按键值 read num case $num in 0) echo "正在转接人工客服,此次通话会被录音";; 1) echo "当话费余额10000";; 2) echo "当前剩余流量100GB";; 3) echo "请输入手机号码以#结束";; 4) echo "请输入身份证号以#结束";; *) echo "请重新输入" esac [root@localhost day02]# sh case.sh 查询话费请按1 查询流量请按2 办理流量套餐请按3 办理宽带业务请求按4 转接人工客服请按0 2 当前剩余流量100GB [root@localhost day02]#
四、循环语句
1、for循环—循环范围确定的情况
根据变量的不同取值,重复执行命令序列
for循环范例,循环输出数字和字符 [root@localhost day02]# vim for.sh #!/bin/bash for i in 8 ab 9 do echo "I am $i" done [root@localhost day02]# sh for.sh I am 8 I am ab I am 9
案例: 打印10遍helloworld [root@localhost day02]# vim for1.sh #!/bin/bash for((i=1;i<=10;i++)) do echo "hello world" done [root@localhost day02]# sh for1.sh hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world
2、While循环—循环范围不确定的情况
反复测试条件,只要成立就执行命令序列
练习while循环基本用法 [root@localhost day02]# vim while.sh #/bin/bash #多少年可以攒够首付 10000*100*0.3---300000 首付 工资 5000 money=0 price=300000 num=0 while [ $money -lt $price ] do let money=money+5000 let num=num+1 done echo $num [root@localhost day02]# sh while.sh 60
五、sed
1、概念
sed全名---Stream Editor 流编辑器,用程序的方式来编辑文本,功能强大。sed是grep的继任者。与vim 不同,sed是一种非交互式的编辑器(就是用户不用参与编辑的过程),他预先设定好了编辑指令对输入文本进行编辑,完成之后再输出。sed基本上就是根据正则进行匹配。sed会一次处理一行。处理时会把待处理的行放到缓冲区,成为“模式空间”,接着sed命令处理缓冲区的数据,处理完了之后把缓冲区的内容送往屏幕展示,这样不断重复直到文件末尾。文件内容并没有被改变 ,除非使用重定向存储文件文件内容会被修改。
2、工作原理
sed会一次处理一行。处理时会把待处理的行放到缓冲区,成为“模式空间”,接着sed命令处理缓冲区的数据,处理完了之后把缓冲区的内容送往屏幕展示,这样不断重复直到文件末尾。文件内容并没有被改变 ,除非使用重定向存储文件文件内容会被修改。
3、正则匹配的过程
就是拿着正则匹配的字符串和原串的内容进行匹配,直到原串中有一个完整的子串就表示匹配成功。"this is better desk"---原串 正则匹配字符串---"esk",这里先拿e和原串进行比较,找到b后面的第一个e,接着往后匹配s匹配没有成功,重新还是从e开始匹配从原串的第二个t往后走,遇到e接着匹配s发现匹配不成功,接着拿着e从原串d开始匹配后面成功。
4、语法格式
sed 选项 (定位符)指令 文件名 (定位符)指令---想对文件的哪一行进行操作
-n屏蔽默认输出
-r支持扩展正则
-i写入文件
5、数据定位
(1)行号定位
sed可以使用行号来定位要去编辑的数据内容
不加选项-n默认先全文打印再执行命令打印第二行 [root@localhost day04]# sed "2p" /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 [root@localhost day04]#
加上-n不全文打印 [root@localhost day04]# sed -n "2p" /etc/hosts ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
打印第三行 [root@localhost day04]# sed -n "3p" /etc/passwd daemon:x:2:2:daemon:/sbin:/sbin/nologin
打印一到三行 [root@localhost day04]# sed -n "1,3p" /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin
打印奇数行 (行数从1开始每次自加2) [root@localhost day04]# sed -n "1~2p" /etc/passwd 打印偶数行 (行数从2开始每次自加2) [root@localhost day04]# sed -n "2~2p" /etc/passwd
打印第二行以及后面相邻的三行 (行数,+数字)---表示行数以及后面相邻的数字行 [root@localhost day04]# sed -n "2,+3p" /etc/passwd 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
(2)正则定位
sed可以使用正则匹配需要数据然后编辑数据
过滤出现root开头的行 [root@localhost day04]# grep "^root" /etc/passwd sed -n "/^root/p" /etc/passwd
过滤三位数 grep -E "[0-9]{3}" /etc/passwd sed -rn "/[0-9]{3}/p" /etc/passwd
6、sed修改配置
Sed编辑指令:
p(print) :打印行
d(delete):删除行
c(replace):替换行
s(substitution):替换关键字
=:打印行号
(1)过滤数据
root@svr7 day04]# sed -n "/IPADDR/p" /etc/sysconfig/network-scripts/ifcfg-ens33 #过滤网卡IP地址 [root@svr7 day04]# free | sed -n "/Mem/p" #过滤内存信息 [root@svr7 day04]# df -h | sed -n "/\/$/p" #过滤磁盘根分区信息 以/结尾的行 [root@svr7 day04]# sed -n "1p;3p;6p" /etc/passwd #打印不连续的多行 [root@svr7 day04]# sed -n '2!p' /etc/passwd #不打印第二行,其他都打印
(2)删除数据
如果不指定定位符默认匹配全文匹配 指定-i选项就可以删除原文件 [root@localhost ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 [root@localhost ~]# sed 'd' /etc/hosts [root@localhost ~]# [root@localhost ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 [root@localhost ~]#
把系统文件数据重定向导临时目录进入目录中 [root@localhost ~]# cat /etc/fstab > /tmp/fstab [root@localhost ~]# cd /tmp/ [root@localhost tmp]# sed '1d' fstab 删除一行 [root@localhost tmp]# sed '1,3d' fstab 删除一到三行 [root@localhost tmp]# sed '/dev/!d' fstab 删除不包含dev的行(取反 !在定位符的后面) [root@localhost tmp]# sed '/^#/d' fstab 删除以#开头的行 [root@localhost tmp]# sed '/^$/d' fstab 删除空行 永久删除--删除1-4行 [root@localhost tmp]# sed -i '1,4d' fstab
(3)替换行
格式:sed '定位符c 要替换的新的内容' 文件
[root@localhost tmp]# sed 'c 123' fstab ---将所有行进行替换为123 [root@localhost tmp]# sed '/IPADDR/c IPADDR=1.1.1.1' /etc/sysconfig/network-scripts/ifcfg-ens33 替换网卡 信息的ip地址为IPADDR=1.1.1.1 把/etc/hosts文件中的第一行替换成127.0.0.1 localhost [root@localhost tmp]# sed '/^1/c 127.0.0.1 localhost' /etc/hosts [root@localhost tmp]# sed '/12/c 127.0.0.1 localhost' /etc/hosts [root@localhost tmp]# sed '/127/c 127.0.0.1 localhost' /etc/hosts [root@localhost tmp]# sed '/4$/c 127.0.0.1 localhost' /etc/hosts [root@localhost tmp]# sed '4c XXXX' /etc/shells 把第四行替换XXXX
(4)替换关键字
格式:s/旧的/新的
新建文件 [root@localhost day04]# vim test.txt [root@localhost day04]# cat test.txt 2046 2048 2046 2046 1001 2046 2999 1888 2046 2046 2046 2046 s默认是每一行 数字s(数字行) 最后一个 /区域默认就是第一个旧的---g(每一个旧的) 区域(哪一行)s/旧的/新的/区域(哪一个旧的) [root@localhost day04]# sed 's/2046/XXXX/' test.txt 将每一行的第一个2026替换成XXXX root@localhost day04]# sed 's/2046/XXXX/g' test.txt 将每一行的每一个2046替换成XXXX [root@localhost day04]# sed 's/2046/XXXX/2' test.txt 将每一行的第二个旧的替换成XXXX [root@localhost day04]# sed 's/2046/(&)/' test.txt 将每一行的2046替换成(2046) ---&可以使用旧的内容 [root@localhost day04]# sed '2s/2046 /XXXX/g' test.txt 将第二行的所有2046替换成XXXX [root@localhost day04]# sed '2s/2046//g' test.txt 新的内容为空就是删除这个数据 [root@localhost day04]# sed -n '2s/2046/XXXX/p' test.txt 将第二行的第一个2046替换成XXXX并且打印 1001 XXXX 2999 1888