shell脚本(变量、判断语句、循环语句、sed)

一、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

  • 36
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值