一、shell 脚本
1.基本概念
shell脚本就是由Shell命令组成的执行文件,将一些命令整合到一个文件 中,进行处理业务逻辑,脚本不用编译即可运行,它从一定程度上减轻 了工作量,提高了工作效率,还可以批量、定时处理主机,方便管理员 进行设置或者管理。
可以简单将shell看作是用户和操作系统之间的命令解释器
2.shell 脚本编写注意事项
shell脚本名称命名一般为英文、大写、小写、后缀以.sh结尾
不能使用特殊符号、空格 名称要写的一眼可以看出功能,也就是顾名思义
shell脚本首行需要#!/bin/bash开头
shell脚本变量不能以数字、特殊符号开头,可以使用下划线 _,但不能 用破折号——
Shell 的返回值:运行一条命令,都会有一个返回值。 0 代表执行正常,非 0 代表命令执行异常。
3.shell 脚本的构成
(1)脚本声明
(2)注释信息
(3)可执行语句
二、简单脚本的创建和运行
1.编写脚本
[root@shell ~]# vim hello.sh
2.运行脚本
方法一:bash
[root@shell ~]# bash hello.sh
hello world!
方法二:sh
[root@shell ~]# sh hello.sh
hello world!
方法三:source
[root@shell ~]# source hello.sh
hello world!
方法四:x先赋予x权限,然后 ./
[root@shell ~]# chmod +x hello.sh
[root@shell ~]# ./hello.sh
hello world!
三、编写nginx安装脚本
用shell脚本自动化部署安装nginx
方法一:
第一步:创建一个shell目录
[root@shell ~]# mkdir shell
进入创建的目录
[root@shell ~]# cd /root/shell/
第二步:编写脚本
[root@shell shell]# vim install_nginx.sh
第三步:执行脚本
给脚本赋予x权限
[root@shell shell]# chmod +x install_nginx.sh
执行脚本
[root@shell shell]# ./install_nginx.sh
方法2:
编写脚本
[root@shell ~]# vim nginxinstall.sh
运行脚本
[root@shell ~]# bash nginxinstall.sh
三、变量
1.变量命名规则:
必须由大写字母、小写字母、下划线、数字,并且首字 母不能是数字
2.变量值的类型:
值的类型会分为整型、浮点型、字符串型、布尔型等, 而且使用变量需要指定类型Shell 默认的变量类型都是字符串,无需指 定类型
3.变量的分类
(1)自定义变量
由用户自己定义、使用和修改
变量名=值中,等于号=之前和之后不能有空格
(2)环境变量
由系统维护,用于设置工作环境
$PWD
$SHELL
$USER
$PATH
PATH变量用于设置可执行程序的默认搜索路径,可以修改全局变 量文件/etc/profile 或修改某用户家目录下的~/.bash_profile文件永久改 变环境变量。
[root@localhost ~]# env # 查看所有环境变量
(3)位置变量
通过命令行给脚本程序传递参数 (也属于预定义变量)
为了在使用Shel脚本程序时,方便通过命令行为程序提供操作参数, Bash引入了位置变量的 概念位置变量有 ,n,n为1~9之间的数字
$0:第一个字段表示命令名或脚本名称
$1:脚本要处理的第一个参数
$2:脚本要处理的第二个参数
Shell脚本最多可以直接处理9个参数
( 4 )预定义变量
Bash中内置的一类变量,不能直接修改
预定义变量是Bash程序预先定义好的一类特殊变量,用户只能使用预定义变量,而不能创建 新的预定义变量,也不能直接为预定义变量赋值。
$*:将所有参数作为整体
$@:单个参数的组合,每个参数占一行
$0:保存了脚本名称
$?:保存命令或脚本的执行状态码
$#:保存脚本要处理的参数的个数
4 、变量的定义与输出
( 1 )定义一个新的变量
格式:变量名 = 变量值
注意:变量名必须以字母或下划线开头,严格区分大小写
(2)变量符号运用
双引号:允许通过 $ 符号引用其他变量值
单引号:禁止引用其他变量值, $ 视为普通字符
反撇号: 或 $(): 命令替换,提取命令的执行结果
(3)输入和输出
输入格式: read [-p " 显示的提示信息 "] 变量名
输出格式: echo $ 变量名
5 、变量的作用范围
默认情况下,新定义的变量只在当前 Shell 环境中有效,因此称为局部变量。当进入子程序或新的子shell 时,局部变量将无法再使用。
为了使用户定义的变量在所有子 Shell 环境中能够继续使用,减少重复设置工作,可以通过内部命令export 将指定的变量导出为 “ 全局变量 ” 。
格式 1 : export 变量名
格式 2 : export 变量名 = 值
6、变量的数学运算
(1)整数运算
格式: expr 变量 1 运算符 变量 2 运算符 变量 3....
运算符: + - * / ( + - × ÷ )
(2)精度计算
精度计算前,先安装bc这个软件才可进行,否则只能进行整数运算
yum -y install bc
四、条件判断语句
1 、 if 单分支语句
if 条件判断 ; then
条件成 ⽴ 执 ⾏ 的命令 ( 可以有多个命令,命令执行方式为逐行执行要么全执行,要么全不执行 )
fi
2 、 if 多分支语句
if 条件判断 ; then
条件成 ⽴ 执 ⾏ 的命令 ( 可以有多个命令 )
else
条件不成 ⽴ 执 ⾏ 的命令 ( 可以有多个命令 )
fi
条件判断:可以有数字判断、字符串判断、⽂件判断等
(一)数字判断
1 、格式
-eq : equal ,等于,一般用于 [ $? -eq 0 ] ,也就是判断上条命令返回值等于 0 ,直接数字 -eq 数
字也可以 equals
-ne : not equal ,不等于,一般用于 [ $? -ne 0 ] ,判断上条命令返回值不等于 0
-gt : greater than ,大于
-ge : greater or equal ,大于或等于
-lt : less than ,小于
-le : less or equal ,小于或等于
2.创建简单的数字判断脚本
3.编写检测网络是否畅通的脚本
第一步:创建脚本
[root@shell ~]# vim ping.sh
第二步:执行脚本
[root@shell ~]# bash ping.sh
(二)字符串判断
1 、格式
[ 字符串 1 == 字符串 2 ] 字符串内容相同
[ 字符串 1 != 字符串 2 ] 字符串内容不同
[ -z 字符串 ]
字符串内容为空
[ -n 字符串 ]
字符串内容不为空
2.案例
( 1 )创建简单的字符串判断脚本
[root@localhost test]# vim zifu.sh
#!/bin/bash
read -p "请输⼊账号:" name
if [ "$name" == "admin" ];then # 字符串判断需要加双引号
echo "欢迎您,$name!"
else
echo "系统未查询到此账号,请您重新输⼊!"
fi
:wq
[root@localhost test]# sh ./zifu.sh
请输⼊账号:admin
欢迎您,admin!
[root@localhost test]# sh ./zifu.sh
请输⼊账号:ads
系统未查询到此账号,请您重新输⼊!
[root@localhost test]#
( 2 )创建 rpm 查询软件是否安装的脚本
[root@localhost test]# vim rpm.sh
#!/bin/bash
read -p "请输⼊你要检测的rpm包:" rpmname # 命令行输入rpmname变量值
result=`rpm -qa $rpmname` # 设置result变量为`rpm -qa $rpmname`命令
if [ -z "$result" ];then # 判断result变量内的命令执行后的值是否为空
echo "${rpmname} is not find!" # 如果为空则输出这条
else
echo "${rpmname} is find!" # 否则输出这条
fi
:wq
[root@localhost test]# sh ./rpm.sh
请输⼊你要检测的rpm包:nginx
nginx is not find!
[root@localhost test]# sh ./rpm.sh
请输⼊你要检测的rpm包:lrzsz
lrzsz is find!
(三)文件判断
文件、目录、权限的判断
1 、格式
[ 操作符 文件或目录 ]
常用的测试操作符 :
2、测试
[root@localhost test]# [ -e "/etc/passwd" ] # 判断/etc/passwd文件是否存在
[root@localhost test]# echo $?
0
[root@localhost test]# [ -e "/etc/haha" ] # 判断/etc/haha文件是否存在
[root@localhost test]# echo $?
1
[root@localhost test]# [ -f "/etc" ] # 判断/etc是否为普通文件
[root@localhost test]# echo $?
1
[root@localhost test]# [ -x "/bin/bash" ] # 判断/bin/bash是否可执行
[root@localhost test]# echo $?
0
nginx 安装脚本优化,判断是否已安装 nginx
[root@localhost test]# vim install_nginx.sh
#!/bin/bash
if [ -e "/usr/local/nginx" ];then # -e:判断nginx软件目录是否存在
echo "nginx is install!" # 存在则输出一条nginx已安装的提示信息
exit 1 # 输出完已安装信息则退出脚本
else # 若nginx软件目录不存在,则执行如下命令
yum -y install gcc gcc-c++ make pcre-devel openssl-devel wget
cd /usr/local/src/
wget 'http://nginx.org/download/nginx-1.22.1.tar.gz'
tar xf nginx-1.22.1.tar.gz
cd nginx-1.22.1
./configure --prefix=/usr/local/nginx
make -j 4&& make install
ln -s /usr/local/nginx/sbin/nginx /usr/bin/
/usr/local/nginx/sbin/nginx
fi
:wq
[root@localhost test]# sh ./install_nginx.sh
五、与或判断
判断多个条件
多个条件其中一个成立,或
多个条件都
要成立,与
或运算判断: ||
或,两个条件满足其一即可,还有 -o
与运算判断: && 与,两个条件都得满足才行,还有 -a
1 、或运算判断
这两个条件需满足其一
[root@localhost test]# vim huo.sh
#!/bin/bash
read -p "请输⼊字符串:" name
if [ "$name" == "haha" ]||[ "$name" == "hehe" ];then # 这两个条件需满足其一,也可使⽤[ "$name" =="haha" -o "$name" == "hehe" ]
echo "$name is my want"
else
echo "in else"
fi
:wq
[root@localhost test]# sh ./huo.sh
请输⼊字符串:haha
haha is my want
[root@localhost test]# sh ./huo.sh
请输⼊字符串:hehe
hehe is my want
[root@localhost test]# sh ./huo.sh
请输⼊字符串:lala
in else
2、与运算判断
这两个条件都得满足
[root@localhost test]# vim yu.sh
#!/bin/bash
read -p "请输⼊⼀个数值:" age
if [ $age -gt 30 ]&&[ $age -lt 80 ];then # 这两个条件都得满足,大于30且小于80,可使用[ $age -gt 30 -a $age -lt 80 ]
echo "age>30 and age<80"
echo "working"
else
echo "in else"
fi
:wq
[root@localhost test]# sh ./yu.sh
请输⼊⼀个数值:60
age>30 and age<80
working
[root@localhost test]# sh ./yu.sh
请输⼊⼀个数值:90
in else
3 、混合判断
[root@localhost test]# vim hun.sh
#!/bin/bash
read -p "请输⼊⼀个数值:" age
if [ $age -gt 2 ]&&[ $age -lt 10 ]||[ $age -eq 100 ];then # 先做||前面的与判断,再进行或判断,可使⽤[ $age -gt 2 -a $age -lt 10 -o $age -eq 100 ]
echo "age is>2 and age is <10 or age ==100 "
else
echo "in else"
fi
:wq
[root@localhost test]# sh ./hun.sh
请输⼊⼀个数值:7
age is>2 and age is <10 or age ==100
[root@localhost test]# sh ./hun.sh
请输⼊⼀个数值:100
age is>2 and age is <10 or age ==100
[root@localhost test]# sh ./hun.sh
请输⼊⼀个数值:30
in else
六、多重判断语法 elif
1 、 if 多分支语句结构
if 条件1; then
#命令,条件1成⽴执⾏
elif 条件2;then
#命令,条件1不成⽴,条件2成⽴执⾏
elif 条件3;then
#命令,条件1不成⽴,条件2不成⽴,条件3成⽴执⾏
else
#命令 ,以上条件都不成⽴执⾏
fi
2 、测试
[root@localhost test]# vim fs.sh
#!/bin/bash
#分数等级评定
read -p "请输⼊您的分数(0-100):" fs
if [ $fs -ge 0 -a $fs -lt 60 ];then
echo "$fs分,不及格!"
elif [ $fs -ge 60 -a $fs -lt 70 ];then
echo "$fs分,及格!"
elif [ $fs -ge 70 -a $fs -lt 85 ];then
echo "$fs分,良好!"
elif [ $fs -ge 85 -a $fs -le 100 ];then
echo "$fs分,优秀!"
else
echo "您输⼊的分数有误!"
fi
:wq
[root@localhost test]# sh ./fs.sh
请输⼊您的分数(0-100):20
20分,不及格!
[root@localhost test]# sh ./fs.sh
请输⼊您的分数(0-100):85
85分,优秀!
[root@localhost test]# sh ./fs.sh
请输⼊您的分数(0-100):70
70分,良好!
[root@localhost test]# sh ./fs.sh
请输⼊您的分数(0-100):123
您输⼊的分数有误!
七、多重判断的 case 语句
case 语句是多分支选择语句, case 还支持正则。
1、 case 语句的结构
case $变量名称 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
*)
默认命令序列
esac
2、测试
实例1: 提示用户输入一个字符,判断该字符是字母、数字或者其他字符的脚本
[root@localhost test]# vim hitkey.sh
#!/bin/bash
#击键类型识别
read -p "请输⼊⼀个字符,并按Enter键确认:" key
case $key in
[a-z]|[A-Z]) # a到z或A到Z,当变量输入为字母则执行下面的echo命令
echo "您输⼊的是⼀个 字⺟"
;;
[0-9]) # 0到9,当变量输入为数字则执行下面的echo的命令
echo "您输⼊的是⼀个 数字"
;;
*) # 若变量输入为空格等其他符号字符,则执行下面的echo命令
echo "您输⼊的是 空格、功能键或其他控制字符"
;;
esac
:wq
[root@localhost test]# sh ./hitkey.sh
请输⼊⼀个字符,并按Enter键确认:5
您输⼊的是⼀个 数字
[root@localhost test]# sh ./hitkey.sh
请输⼊⼀个字符,并按Enter键确认:b
您输⼊的是⼀个 字⺟
[root@localhost test]# sh ./hitkey.sh
请输⼊⼀个字符,并按Enter键确认:P
您输⼊的是⼀个 字⺟
[root@localhost test]# sh ./hitkey.sh
请输⼊⼀个字符,并按Enter键确认:!
您输⼊的是 空格、功能键或其他控制字符
实例2: 输入分数变量,然后判定等级脚本
[root@localhost test]# vim fscase.sh
#!/bin/bash
#使⽤case语句编写分数等级评定脚本
read -p "请输⼊您的分数(0-100):" fs
case $fs in
[0-9]|[0-5][0-9]) # 0到9或59以内的两位数
echo "$fs分,不及格!"
;;
6[0-9]) # 6开头的两位数,若$fs输入为0,则判定为60,即执行下面的echo命令
echo "$fs分,及格!"
;;
7[0-9]|8[0-5]) # 以7开头的两位数或以8开头的两位数
echo "$fs分,良好!"
;;
8[6-9]|9[0-9]|100) # 以8开头的两位数,第二位最少为6,也就是最小是86 | 以9开头的两位数 | 100
echo "$fs分,优秀!"
;;
*) # 输入不在上述规则内的其他字符,则echo如下命令
echo "您输⼊的分数有误!"
esac
:wq
[root@localhost test]# sh ./fscase.sh
请输⼊您的分数(0-100):5
5分,不及格!
[root@localhost test]# sh ./fscase.sh
请输⼊您的分数(0-100):58
58分,不及格!
[root@localhost test]# sh ./fscase.sh
请输⼊您的分数(0-100):69
69分,及格!
[root@localhost test]# sh ./fscase.sh
请输⼊您的分数(0-100):70
70分,良好!
[root@localhost test]# sh ./fscase.sh
请输⼊您的分数(0-100):89
89分,优秀!
[root@localhost test]# sh ./fscase.sh
请输⼊您的分数(0-100):100
100分,优秀!
[root@localhost test]# sh ./fscase.sh
请输⼊您的分数(0-100):110
您输⼊的分数有误!
八、脚本循环语句
(一)for 循环
1 、作用
读取不同的变量值,以逐个执行同一组命令
2 、结构
for 变量名 in 取值列表 ( 范围 )
do
命令序列
done
取值列表:数字范围、字符串、多个字符串、提前设定好的变量等
for 默认以所有的空白字符进行分隔 : tab 、空格、回车,去循环处理
分隔成几段就循环几次
3 、示例
( 1 )分隔值循环
[root@localhost test]# vim quzhi.sh
#!/bin/bash
for home in 北京 上海 ⼴州 深圳 # home变量在北京、上海、广州、深圳这四个地名中间循环一次
do
echo "$home 是个好地⽅!"
done
:wq
[root@localhost test]# bash quzhi.sh
北京 是个好地⽅!
上海 是个好地⽅!
⼴州 是个好地⽅!
深圳 是个好地⽅!
实例:判断包是否已安装
[root@localhost test]# vim 2.sh
#!/bin/bash
for softpack in wget gcc pcre pcre-devel zlib zlib-devel
do
soft_result=$(rpm -qa $softpack)
if [ -z "$soft_result" ];then
yum install -y $softpack
else
echo "$softpack is installed"
fi
done
[root@localhost test]# bash 2.sh
wget is installed
gcc is installed
pcre is installed
pcre-devel is installed
zlib is installed
zlib-devel is installed
( 2 )在命令结果中循环
[root@localhost test]# vim 1.sh
#!/bin/bash
x=1
for user in $(awk -F':' '{print $1}' /etc/passwd) # 在/etc/passwd文件中以用户名作为循环
do
echo "第 $x ⽤户名称为: $user"
let x=x+1
done
echo "该系统有 $(($x-1)) 个⽤户"
:wq
[root@localhost test]# bash 1.sh
第 1 ⽤户名称为: root
...省略部分内容
第 45 ⽤户名称为: yunjisuan
第 46 ⽤户名称为: apache
第 47 ⽤户名称为: nginx
该系统有 47 个⽤户
实例:检测某个网段的存活主机
[root@localhost test]# vim ping.sh
#!/bin/bash
for IP in $(echo 192.168.33.{100..120}) # 192.168.33网段的100到120的主机,在此循环
do
ping -c 2 -i 0.1 $IP &> /dev/null
if [ $? -eq 0 ];then
echo "Host $IP is up."
fi
done
:wq
[root@localhost test]# bash ping.sh
Host 192.168.100.100 is up.
Host 192.168.100.101 is up.
(二)while 循环
1 、作用
重复测试某个条件,只要条件成立则反复执行
2 、结构
while 条件测试操作
do
命令序列
done
3 、 while 和 for 区别
while 循环也有条件判断,当条件成立的时候,会循环执行。当条件不成立退出
if 判断当条件成立时,会执行一次,然后退出。当条件不成立时直接退出
4、测试
批量添加用户
创建时交互输入用户前缀、创建用户个数、初始密码、过期时间(可选设置),用户首次登陆强制要求修改密码
[root@localhost test]# vim useradd.sh # 批量创建⽤户脚本
#!/bin/bash
read -p "请输⼊创建⽤户的名称前缀:" QZ
read -p "请输⼊创建⽤户的个数:" NUM
read -p "请输⼊⽤户的初始密码:" PS
i=1
while [ $i -le $NUM ]
do
useradd $QZ$i
echo "$PS" | passwd --stdin $QZ$i &> /dev/null
chage -d 0 $QZ$i
let i++
done
:wq
[root@localhost test]# bash useradd.sh
请输⼊创建⽤户的名称前缀:admin
请输⼊创建⽤户的个数:5
请输⼊⽤户的初始密码:123456
[root@localhost test]# tail /etc/passwd
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
yunjisuan:x:1000:1000:yunjisuan:/home/yunjisuan:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
nginx:x:975:974:Nginx web server:/var/lib/nginx:/sbin/nologin
admin1:x:1001:1001::/home/admin1:/bin/bash
admin2:x:1002:1002::/home/admin2:/bin/bash
admin3:x:1003:1003::/home/admin3:/bin/bash
admin4:x:1004:1004::/home/admin4:/bin/bash
admin5:x:1005:1005::/home/admin5:/bin/bash
批量删除用户
[root@localhost test]# vim userdel.sh # 批量删除⽤户脚本
#!/bin/bash
read -p "请输⼊要删除⽤户的前缀:" QZ
read -p "请输⼊要删除⽤户的个数:" NUM
i=1
while [ $i -le $NUM ]
do
userdel -r $QZ$i
let i++
done
:wq
[root@localhost test]# bash userdel.sh
请输⼊要删除⽤户的前缀:admin
请输⼊要删除⽤户的个数:5
(三) break 和 continue
break 直接结束循环,循环立即退出
continue 可以用来跳过一次循环,跳过后循环继续,直到循环停止
实例:
[root@localhost test]# vim test.sh
#!/bin/bash
for line in 北京 上海 ⼴州 深圳
do
echo $line
if [ "$line" == "上海" ];then # 循环到上海⽴即退出
break
fi
done
:wq
[root@localhost test]# bash test.sh
北京
上海
[root@localhost test]# vim test.sh
#!/bin/bash
for line in 北京 上海 ⼴州 深圳
do
if [ "$line" == "上海" ];then
continue
fi
echo $line
done
:wq
[root@localhost test]# bash test.sh
北京
⼴州
深圳
(四)九九乘法表
方法一:
[root@localhost test]# vim 99.sh
#!/bin/bash
#九九乘法表
for i in {1..9};do
for j in {1..9};do
echo -n "$j*$i=$(($i*$j)) "
if [ $j == $i ];then
echo -e '\n'
break
fi
done
done
:wq
运行结果:
[root@localhost test]# bash 99.sh
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
方法二:
[root@localhost test]# vim 99-2.sh
#!/bin/bash
#九九乘法表
i=1
while [ $i -le 9 ];do
j=1
while [ $j -le 9 ];do
echo -n "$j*$i=$(($i*$j)) "
if [ $j -eq $i ];then
echo -e '\n'
break
fi
let j++
done
let i++
done
:wq
运行结果:
[root@localhost test]# bash 99-2.sh
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
九、sed流式编辑器
(1)概述
sed 是文本处理工具,读取文本内容,根据指定条件进行处理,可实现增删改查的功能。
sed 依赖于正则表达式。
1、格式
sed 选项 “(定位符)指令” 文件名
(定位符)指令---想对文件的哪一行进行操作
2、选项
3、行号定位
[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
加上-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
打印第一行和第三行
[root@lib ~]# sed -n '1p;3p' ifcfg-ens33
TYPE=Ethernet
BROWSER_ONLY=no
打印奇数行 (行数从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
4、正则定位
基本正则
sed可以使用正则匹配需要数据然后编辑数据
过滤出现root开头的行
[root@localhost day04]# sed -n "/^root/p" /etc/passwd
过滤三位数
[root@localhost day04]# sed -rn "/[0-9]{3}/p" /etc/passwd
(2)sed修改配置
[root@lib ~]# sed -i '4d' ifcfg-ens33 //删除第四行
[root@lib ~]# sed -i '3aBOOTPROTO="dhcp"' ifcfg-ens33 //将指定内容追加到第三行后面
[root@lib ~]# sed -i '/dhcp/ s/dhcp/none/g' ifcfg-ens33 //定位到dhcp的一行,并将dhcp换为none
(3)sed命令引用变量
1、sed命令使用单引号的情况下,可以使用 '"$var"' 引用(单引号,然后 双引号,变量):
sed -i '2s/node_base/'"$i"'/' /etc/libvirt/qemu/$i.xml
2、sed命令中使用双引号的情况下,直接 shell command 或者 $(shell command) 引用命令执行。
sed -i "2s/node_base/$i/" /etc/libvirt/qemu/$i.xml
(4)练习
配置一个自动设置静态ip以及关闭selinux服务 关闭防火墙服务 关闭NetworkManager 修改主机名称的脚本
ip和主机名称使用read输入 //uuidgen为重新生成一个uuid
[root@lib ~]# vim server.sh
#!/bin/bash
read -p "现在请输入一个你想要的ip地址:" ip
sed -i 's/dhcp/none/g' /etc/sysconfig/network-scripts/ifcfg-ens33
sed -i '$a IPADDR='"$ip"'\nNETMASK=255.255.255.0\nGATEWAY=10.0.0.2\nDNS1=8.8.8.8\nDNS2=114.114.114.114' /etc/sysconfig/network-scripts/ifcfg-ens33
sed -i '/UUID/c UUID='"$(uuidgen)"'' /etc/sysconfig/network-scripts/ifcfg-ens33
systemctl stop firewalld
systemctl disable firewalld
systemctl stop NetworkManager
systemctl disable NetworkManager
setenforce 0
read -p "现在请输入你想要的主机名:" hostname
hostnamectl set-hostname $hostname
echo "注意:在重启后用户名才会生效,重启命令为reboot"
[root@lib ~]# source server.sh
现在请输入一个你想要的ip地址:10.0.0.200
setenforce: SELinux is disabled
现在请输入你想要的主机名:hh
注意:在重启后用户名才会生效,重启命令为reboot
[root@lib ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
UUID=b3234856-4ff2-42bc-bb28-34deced3b945
DEVICE=ens33
ONBOOT=yes
IPADDR=10.0.0.200
NETMASK=255.255.255.0
GATEWAY=10.0.0.2
DNS1=8.8.8.8
DNS2=114.114.114.114