shell编程
2025-12-30 17:22:17 0 举报
AI智能生成
1
作者其他创作
大纲/内容
Linux安装
常用的Linux系统
红帽 HedHat CentOS (停止维护)Rocky(代替CentOS)Ubuntu (桌面型)
安装Rocky系统
1)在VMware中点击文件,新建虚拟机,选择典型
2)选择ISO文件
3)选择Linux版本(默认)
4)设置名称和保存位置
5)磁盘大小(默认)
6)点击完成
7)启动虚拟机
8)选择安装Rocky
9)语言(默认)
10)设置安装位置和密码
11)安装位置选择
12)设置root密码
13)点击开始安装
14)重启
15)输入账号密码登录系统
配置静态IP
1)输入命令
vi /etc/sysconfig/network-scripts/ifcfg-ens33
vi /etc/sysconfig/network-scripts/ifcfg-ens33
2)查看网关(编辑 > 虚拟网络编辑器)
NAT设置
NAT设置
3)在vi命令中,按 i 进入编辑模式 (下面出现INSERT文字)
编辑后按esc退出编辑模式,输入 :wq 保存退出
编辑后按esc退出编辑模式,输入 :wq 保存退出
4)重启网络
systemctl restart NetworkManager
systemctl restart NetworkManager
5)查看ip
ip a
ip a
6)使用final_shell工具连接
目录和文件操作
Linux目录结构
树状结构,根节点是 /
/
/bin 命令目录
/root 管理员目录
/usr 用户目录
/home 家目录
/mnt 文件挂载目录
....
/bin 命令目录
/root 管理员目录
/usr 用户目录
/home 家目录
/mnt 文件挂载目录
....
查看目录
ls
查看目录中的内容
用法:
ls 目录路径 查看特定目录
ls 查看当前目录
常用选项:
-l 详细信息
-a 所有文件(包含隐藏文件)
ls 目录路径 查看特定目录
ls 查看当前目录
常用选项:
-l 详细信息
-a 所有文件(包含隐藏文件)
示例1:查看根目录下的内容
ls /
ls /bin
ls
ls -l /etc 查看etc目录的详细内容
ls -a / 查看根目录的所有文件
ls /
ls /bin
ls
ls -l /etc 查看etc目录的详细内容
ls -a / 查看根目录的所有文件
||
查看目录的详细信息
等价于 ls -l
等价于 ls -l
示例:查看etc目录的详细内容
ll /etc
ll /etc
tree
查看目录的树状结构
用法:tree 目录路径
示例:查看/etc的树状结构
tree /etc
tree /etc
目录路径
绝对路径
完整路径,从根目录开始 如: /usr/local/bin
相对路径
相对路径,相对当前目录的路径 如:当前目录是/usr/local 可以直接写 bin
切换目录
修改当前的目录位置
cd 目录路径
示例:切换到/usr下的各个目录
pwd
查看当前目录的完整路径
创建目录
mkdir
用法:
mkdir 目录路径 创建一个目录
mkdir 目录1 目录2 ... 创建多个目录
mkdir -p 目录1/目录2/目录3 创建多级目录(-p自动创建上级目录)
mkdir 目录路径 创建一个目录
mkdir 目录1 目录2 ... 创建多个目录
mkdir -p 目录1/目录2/目录3 创建多级目录(-p自动创建上级目录)
示例 1: 在/opt创建hello目录
cd /opt
mkdir hello
ls
cd /opt
mkdir hello
ls
示例2 : 创建多个目录
mkdir hello1 hello2 hello3
或
mkdir test{1..5}
mkdir hello1 hello2 hello3
或
mkdir test{1..5}
示例3:创建多级目录
mkdir -p aa/bb/cc
mkdir -p aa/bb/cc
删除目录
rm 删除目录或文件题
用法:rm [选项] 目录或文件路径
-r 递归删除
-f 强制删除
rm -rf xxxx
-r 递归删除
-f 强制删除
rm -rf xxxx
示例1:删除目录
rm -rf test1
rm -rf test1
示例2:删除多个目录
rm -rf test{1..5}
rm -rf h* h开头文件
rm -rf * 当前目录的所有文件
rm -rf test{1..5}
rm -rf h* h开头文件
rm -rf * 当前目录的所有文件
复制目录
cp 复制目录或文件
用法:cp 源文件路径 目标文件路径
选项 :复制目录要加 -r 递归复制
选项 :复制目录要加 -r 递归复制
示例:
mkdir aaa
cp -r aaa bbb
mkdir aaa
cp -r aaa bbb
移动目录
mv 移动目录或文件
用法: mv 源文件路径 目标文件路径
示例:给aaa重命名为abc
mv aaa abc
mv aaa abc
示例:把bbb移动到/mnt下
mv bbb /mnt/
mv bbb /mnt/
练习:
1)切换到/opt下
cd /opt
2)创建t1~t5 五个同级目录
mkdir t{1..5}
3)创建a1/a2/a3 三个多级目录
mkdir -p a1/a2/a3
4)删除t开头的目录
rm -rf t*
5)修改a1目录的名字为aaa
mv a1 aaa
6)将aaa目录复制为bbb
cp -r aaa bbb
1)切换到/opt下
cd /opt
2)创建t1~t5 五个同级目录
mkdir t{1..5}
3)创建a1/a2/a3 三个多级目录
mkdir -p a1/a2/a3
4)删除t开头的目录
rm -rf t*
5)修改a1目录的名字为aaa
mv a1 aaa
6)将aaa目录复制为bbb
cp -r aaa bbb
文件操作
创建文件
touch 用于创建空文件或修改文件状态
如果文件不存在会创建空文件,存在就会修改文件的状态
如果文件不存在会创建空文件,存在就会修改文件的状态
用法: touch 文件路径
示例1:创建空文件
touch test1
touch test1
示例2:创建多个文件
touch a{1..9}
touch a{1..9}
示例3:修改文件状态
touch a1
touch a1
编辑文件
vi 或 vim (vi的升级版)
可以用于创建并编辑文件的内容
安装vim yum install -y vim
可以用于创建并编辑文件的内容
安装vim yum install -y vim
三种模式:
命令模式 (进入后默认的模式,不能编辑,可以复制粘贴、删除、查找)
编辑模式(命令模式按 i 或 a 进入)
命令行模式(命令模式下按: 进入,可以保存、退出)
命令模式 (进入后默认的模式,不能编辑,可以复制粘贴、删除、查找)
编辑模式(命令模式按 i 或 a 进入)
命令行模式(命令模式下按: 进入,可以保存、退出)
基本命令:1)创建文件
vi test1.txt
2)进入命令模式,按i进入编辑模式,开始输入
3)输入完成后,按esc退出到命令模式
4)输入: 进入命令行模式 wq 保存加退出
vi test1.txt
2)进入命令模式,按i进入编辑模式,开始输入
3)输入完成后,按esc退出到命令模式
4)输入: 进入命令行模式 wq 保存加退出
命令行模式的用法
:w 保存
:q 退出(没有修改时可以退出)
:q! 强制退出(有修改时,不保存退出)
:wq 保存退出
:q 退出(没有修改时可以退出)
:q! 强制退出(有修改时,不保存退出)
:wq 保存退出
高级应用
复制粘贴:
命令模式下
复制一行 yy
粘贴 p
复制多行 数字yy
命令模式下
复制一行 yy
粘贴 p
复制多行 数字yy
删除:
删除一行 dd
删除多行 数字dd
删除一行 dd
删除多行 数字dd
查找文字:
按/ 输入文字
按n切换到下一个
按/ 输入文字
按n切换到下一个
撤销:
按u
按u
显示行号:
输入:set number
输入:set number
粘贴模式:
输入:set paste 回车
按i 进入编辑模式(显示-- INSERT (paste) --)
将文字复制,在界面中右键粘贴
保证文字格式和原来文件一致
输入:set paste 回车
按i 进入编辑模式(显示-- INSERT (paste) --)
将文字复制,在界面中右键粘贴
保证文字格式和原来文件一致
查看文件
cat
查看文件的所有内容
用法:cat 文件路径
more
分页查看文件的内容
用法:more 文件路径
回车显示下一行
按空格显示下一页
按b显示上一页
按"显示第一页
按q退出
回车显示下一行
按空格显示下一页
按b显示上一页
按"显示第一页
按q退出
head
显示文件的头几行
用法: head -数字 文件路径
示例:显示文件的前三行
head -3 test1.txt
head -3 test1.txt
tail
显示文件的后几行
用法:tail -数字 文件路径
示例:显示文件的后两行
tail -2 test1.txt
tail -2 test1.txt
sort
对文件排序
sort 文件名
-r 降序
-r 降序
基本的排序
降序排序
uniq
tar:
压缩和解压文件
压缩包格式:tar\tar.gz\zip
压缩和解压文件
压缩包格式:tar\tar.gz\zip
tar 选项 文件名
选项:
-c 压缩
-x 解压
-v 显示过程
-f 指定文件
-z 压缩格式gz
选项:
-c 压缩
-x 解压
-v 显示过程
-f 指定文件
-z 压缩格式gz
压缩文件
tar -cvf 压缩包文件 文件1 文件2 ...
tar -cvf 压缩包文件 文件1 文件2 ...
示例:
touch test{1..5}
tar -cvf test.tar test{1..5}
touch test{1..5}
tar -cvf test.tar test{1..5}
解压文件
tar -xvf 压缩包文件 (默认解压到当前目录)
-C 指定解压目录
tar -xvf 压缩包文件 (默认解压到当前目录)
-C 指定解压目录
示例:
rm -rf test{1..5}
tar -xvf test.tar
解压到/mnt下
tar -xvf test.tar -C /mnt
rm -rf test{1..5}
tar -xvf test.tar
解压到/mnt下
tar -xvf test.tar -C /mnt
zip格式
zip
压缩zip格式包
zip 包名 文件 ...
zip test.zip test{1..5}
压缩zip格式包
zip 包名 文件 ...
zip test.zip test{1..5}
unzip
解压zip格式包
unzip 压缩包名
unzip test.zip
解压zip格式包
unzip 压缩包名
unzip test.zip
综合案例:安装JDK
1)将jdk安装包上传到/usr/local目录
2)切换到local下,解压安装包
cd /usr/local
tar -xvf jdk-17_linux-x64_bin.tar.gz
cd /usr/local
tar -xvf jdk-17_linux-x64_bin.tar.gz
3)给目录改名为jdk17
mv jdk-17.0.12 jdk17
mv jdk-17.0.12 jdk17
4)配置环境变量,修改profile文件
vi /etc/profile
在末尾加两行:
export JAVA_HOME=/usr/local/jdk17
export PATH=$PATH:$JAVA_HOME/bin
vi /etc/profile
在末尾加两行:
export JAVA_HOME=/usr/local/jdk17
export PATH=$PATH:$JAVA_HOME/bin
5)让环境变量生效
source /etc/profile
source /etc/profile
6)查看java版本
java -version
java -version
文件查找
find
可以通过多种条件来查找文件
用法:find 查找位置 查找条件 值
查找位置
特定位置 如:/etc
全盘查找 /
当前目录 .
全盘查找 /
当前目录 .
按名称查找
-name "名称" 名称可以带*
示例1:在/etc目录查找a开头的文件
find /etc -name "a*"
示例2:全盘查找以.sh结尾的文件
find / -name "*.sh"
示例1:在/etc目录查找a开头的文件
find /etc -name "a*"
示例2:全盘查找以.sh结尾的文件
find / -name "*.sh"
按大小查找
-size 大小 大小可以带单位(k、M、G)+ 大于 - 小于
示例1:在/etc目录查找大于10M的文件
find /etc -size +10M
示例2:全盘查找超过500M的文件
find / -size +500M
示例3:在/etc下查找s开头的,大小在1k到20k之间的文件
find /etc -name "s*" -size +1k -size -20k
示例1:在/etc目录查找大于10M的文件
find /etc -size +10M
示例2:全盘查找超过500M的文件
find / -size +500M
示例3:在/etc下查找s开头的,大小在1k到20k之间的文件
find /etc -name "s*" -size +1k -size -20k
按类型查找
-type 类型 f 普通文件 d 目录 l 链接文件 b 块文件
示例1:在/etc下查找n开头的链接文件
find /etc -name "n*" -type l
示例2:全盘查找a开头的,大于1k的普通文件
find / -name "a*" -size +1k -type f
示例1:在/etc下查找n开头的链接文件
find /etc -name "n*" -type l
示例2:全盘查找a开头的,大于1k的普通文件
find / -name "a*" -size +1k -type f
按时间查找
-ctime 创建时间 -atime 访问时间 -mtime 修改时间
单位是天 2 前两天 +2 两天前 -2 两天内
示例1:在/usr目录下查找小于10k的,三天内创建的文件
find /usr -size -10k -ctime -3
示例2:全盘查找以s开头s结尾的,大小在1k到2M之间的,创建时间在2天到5天内的普通文件
find / -name "s*s" -size +1k -size -1M -ctime +2 -ctime -5 -type f
单位是天 2 前两天 +2 两天前 -2 两天内
示例1:在/usr目录下查找小于10k的,三天内创建的文件
find /usr -size -10k -ctime -3
示例2:全盘查找以s开头s结尾的,大小在1k到2M之间的,创建时间在2天到5天内的普通文件
find / -name "s*s" -size +1k -size -1M -ctime +2 -ctime -5 -type f
文件统计
wc
统计文件的行数、字节数、字符数等信息
用法:wc 选项 文件路径
选项:
-l 行数
-m 字符数
-c 字节数
-L 最长行的长度
-w 单词数
用法:wc 选项 文件路径
选项:
-l 行数
-m 字符数
-c 字节数
-L 最长行的长度
-w 单词数
示例:统计文件信息
管道符
|
将多个命令依次执行,前面命令的执行结果,作为后面命令的输入
用法: 命令1 | 命令2 | 命令3 .....
示例1:统计磁盘上脚本(.sh结尾的文件)的数量
find / -name "*.sh" -type f | wc -l
示例2:统计文件中不重复的内容数量
cat test1 | sort | uniq | wc -l
示例3:显示文件中的3到5行内容 head tail
cat test1 | head -5 | tail -2
用法: 命令1 | 命令2 | 命令3 .....
示例1:统计磁盘上脚本(.sh结尾的文件)的数量
find / -name "*.sh" -type f | wc -l
示例2:统计文件中不重复的内容数量
cat test1 | sort | uniq | wc -l
示例3:显示文件中的3到5行内容 head tail
cat test1 | head -5 | tail -2
重定向
读写文件
>
写入文件,对原有内容进行覆盖
示例1:写入文字到test1中
echo "hello" > test1
示例2:统计磁盘上脚本(.sh结尾的文件)的数量保存到count中
find / -name "*.sh" -type f | wc -l > count
示例1:写入文字到test1中
echo "hello" > test1
示例2:统计磁盘上脚本(.sh结尾的文件)的数量保存到count中
find / -name "*.sh" -type f | wc -l > count
>>
写入文件,对原有内容进行追加
示例1:写入文字到test1中
echo "hello" >> test1
<
从文件读取
示例1:读取文字
cat < test1
示例2:复制文件
cat < test1 > test2
<<
从控制台读取文字,遇到结束符停止
读取文字,写入test文件
cat > test <<EOF
。。。。
。。。。
EOF
读取文字,写入test文件
cat > test <<EOF
。。。。
。。。。
EOF
用户和权限相关操作
Linux是多用户多任务的操作系统,不同的用户具有不同权限
用户分为
超级管理员 root 最高权限 uid 是 0
系统用户 系统自带 uid 在1到999
自定义用户 自己创建的 uid >= 1000
用户相关文件
/etc/passwd 用户信息
用户名:密码:用户ID:组ID:家目录:解释器类型
/etc/shadow 用户密码
用户名:加密后的密码:密码过期时间
/etc/group 用户组信息
组名:密码:组ID
用户相关命令
查看用户s
id 用户名
显示用户名和组的相关信息
创建用户
useradd 选项 用户名
选项:
-g 设置组
-G 设置附加组
-u 设置uid
-d 设置家目录(默认 在/home)
-m 自动创建家目录
选项:
-g 设置组
-G 设置附加组
-u 设置uid
-d 设置家目录(默认 在/home)
-m 自动创建家目录
示例:
1)创建test用户
useradd test
useradd test
创建用户如果没有设置组,会自动创建和用户同名的组
2)创建test1用户,设置组为test
useradd -g test test1
useradd -g test test1
创建用户设置组,不会创建新组
3)创建test2用户,附加组有test和root
useradd -G test,root test2
useradd -G test,root test2
附加组可以有多个
4)创建test3用户,设置uid为1800
useradd -u 1800 test3
useradd -u 1800 test3
5)创建test4用户,设置家目录为/opt/test4
useradd -d /opt/test5 -m test5
useradd -d /opt/test5 -m test5
设置密码
passwd
交互式
passwd 用户名
如:
passwd test
如:
passwd test
非交互式
echo "密码" | passwd 用户 --stdin
--stdin 使用控制台的密码
如:
echo "123456" | passwd test1 --stdin
--stdin 使用控制台的密码
如:
echo "123456" | passwd test1 --stdin
切换用户
su
su 用户名
不会修改当前的目录,不会加载用户的配置
不会修改当前的目录,不会加载用户的配置
su - 用户名
切换到用户的家目录,会加载用户的配置
切换到用户的家目录,会加载用户的配置
修改用户
usermod
用法:usermod 选项 用户
选项和useradd 相同
选项和useradd 相同
示例:
1)修改用户test的id
usermod -u 2000 test
1)修改用户test的id
usermod -u 2000 test
2)修改用户test的组为root
usermod -g root test
usermod -g root test
删除用户
userdel
用法:userdel 选项 用户
选项:
-f 强制删除
-r 删除家目录
选项:
-f 强制删除
-r 删除家目录
示例:
1)userdel test
2)userdel -r test1
1)userdel test
2)userdel -r test1
用户组的操作
查看组
groups 用户
查看用户所属的组
查看用户所属的组
创建组
groupadd 选项 组名
-g 组id
-g 组id
示例:
groupadd hello
groupadd -g 1888 hello1
tail /etc/group
groupadd hello
groupadd -g 1888 hello1
tail /etc/group
修改组
groupmod 选项 组名
-g 组id
-n 组名
-g 组id
-n 组名
示例:
groupmod -g 1999 hello
groupmod -n hello123 hello1
groupmod -g 1999 hello
groupmod -n hello123 hello1
删除组
groupdel 组名
示例:
groupdel hello
groupdel hello
权限的相关操作
文件的权限字符
ll /etc
权限字符串:
第一个字符式文件类型 - 文件 d 目录 l 链接
第2~4个字符所有者权限
第5~7个字符同组用户权限
第8~10个字符其他用户权限
第一个字符式文件类型 - 文件 d 目录 l 链接
第2~4个字符所有者权限
第5~7个字符同组用户权限
第8~10个字符其他用户权限
权限字符:
r 读
w 写
x 执行
- 无
r 读
w 写
x 执行
- 无
权限数字:
0 --- 无
1 --x 执行
2 -w- 写
3 -wx 写+执行
4 r-- 读
5 r-x 读+执行
6 rw- 读写
7 rwx 读写执行
0 --- 无
1 --x 执行
2 -w- 写
3 -wx 写+执行
4 r-- 读
5 r-x 读+执行
6 rw- 读写
7 rwx 读写执行
练习:
1)将下面的权限字符转换为数字
rwxrw-r-- 764
rw-r--r-- 644
rwxr-xr-x 755
2)将下面的数字转换为权限字符
653 rw-r-x-wx
755 rwxr-xr-x
740 rwxr-----
1)将下面的权限字符转换为数字
rwxrw-r-- 764
rw-r--r-- 644
rwxr-xr-x 755
2)将下面的数字转换为权限字符
653 rw-r-x-wx
755 rwxr-xr-x
740 rwxr-----
修改权限
chmod
用法
通过权限数字修改
chmod 权限数字 文件路径
将所有者和同组和其他用户一起设置,不能单独设置
chmod 权限数字 文件路径
将所有者和同组和其他用户一起设置,不能单独设置
示例:
1)修改文件权限为666
chmod 666 1.txt
chmod 777 1.txt
chmod 640 1.txt
1)修改文件权限为666
chmod 666 1.txt
chmod 777 1.txt
chmod 640 1.txt
通过权限字符修改
chmod 字符 文件路径
分组符号:u 所有者 g 同组用户 o 其他用户 a或不写 全部用户
权限符号:=r 设置为读 +r 添加读 -r 删除读
chmod 字符 文件路径
分组符号:u 所有者 g 同组用户 o 其他用户 a或不写 全部用户
权限符号:=r 设置为读 +r 添加读 -r 删除读
示例:
1)给所有者添加写权限
chmod u+w 1.txt
2)把同组用户权限设置为读写
chmod g=rw 1.txt
3)删除其他用户执行权限
chmod o-x 1.txt
4)给所有用户添加写权限
chmod a+w 1.txt
chmod +w 1.txt
1)给所有者添加写权限
chmod u+w 1.txt
2)把同组用户权限设置为读写
chmod g=rw 1.txt
3)删除其他用户执行权限
chmod o-x 1.txt
4)给所有用户添加写权限
chmod a+w 1.txt
chmod +w 1.txt
修改所有者
chown
用法: chown 选项 用户名.[组名] 文件路径
选项 -R 递归修改(修改所有子目录和文件)
选项 -R 递归修改(修改所有子目录和文件)
案例:
1)修改文件所有者,让用户可以读写
[root@localhost opt]# touch hello
[root@localhost opt]# useradd test
[root@localhost opt]# ll
总用量 0
-rw-r--r--. 1 root root 0 12月 9 01:39 hello
[root@localhost opt]# su test
[test@localhost opt]$ echo "555" > hello
bash: hello: Permission denied
[test@localhost opt]$ su root
密码:
[root@localhost opt]# chown test.test hello
[root@localhost opt]# ll
总用量 0
-rw-r--r--. 1 test test 0 12月 9 01:39 hello
[root@localhost opt]# su test
[test@localhost opt]$ echo "666" > hello
[test@localhost opt]$ cat hello
666
[root@localhost opt]# touch hello
[root@localhost opt]# useradd test
[root@localhost opt]# ll
总用量 0
-rw-r--r--. 1 root root 0 12月 9 01:39 hello
[root@localhost opt]# su test
[test@localhost opt]$ echo "555" > hello
bash: hello: Permission denied
[test@localhost opt]$ su root
密码:
[root@localhost opt]# chown test.test hello
[root@localhost opt]# ll
总用量 0
-rw-r--r--. 1 test test 0 12月 9 01:39 hello
[root@localhost opt]# su test
[test@localhost opt]$ echo "666" > hello
[test@localhost opt]$ cat hello
666
2)修改目录所有者,实现递归修改
[root@localhost opt]# mkdir -p aaa/bbb/ccc
[root@localhost opt]# ll
总用量 4
drwxr-xr-x. 3 root root 17 12月 9 01:50 aaa
[root@localhost opt]# chown -R test.test aaa
[root@localhost opt]# ll aaa/bbb
总用量 0
drwxr-xr-x. 2 test test 6 12月 9 01:50 ccc
[root@localhost opt]# mkdir -p aaa/bbb/ccc
[root@localhost opt]# ll
总用量 4
drwxr-xr-x. 3 root root 17 12月 9 01:50 aaa
[root@localhost opt]# chown -R test.test aaa
[root@localhost opt]# ll aaa/bbb
总用量 0
drwxr-xr-x. 2 test test 6 12月 9 01:50 ccc
系统服务和软件管理
系统服务
由系统进行管理的软件服务,可以用systemctl命令管理
systemctl 操作 服务名
操作:
start 启动
stop 停止
restart 重启
reload 重加载
enable 启用(开机自启)
disable 禁用(不开机自启)
status 状态
start 启动
stop 停止
restart 重启
reload 重加载
enable 启用(开机自启)
disable 禁用(不开机自启)
status 状态
常用服务:
firewalld 防火墙
sshd 远程登录
firewalld 防火墙
sshd 远程登录
软件管理
软件安装的方式
源码包
步骤较多,配置灵活
在线安装
安装简单,配置固定
CentOS、Rocky、红帽默认使用yum
Ubuntu默认使用apt
Ubuntu默认使用apt
yum
存在远程软件仓库,用户可以搜索和下载安装软件
CentOS需要配置国内源
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
列举所有软件
yum list
搜索软件
yum search 软件名
yum search 软件名
yum search mysql
安装软件
yum install 软件名
yum install 软件名
yum install vim
yum install -y vim 直接确认
yum install -y vim 直接确认
卸载软件
yum remove 软件名
yum remove -y vim
yum remove 软件名
yum remove -y vim
升级软件
yum upgrade
yum upgrade
更新软件
yum update 软件名
yum update 软件名
yum update vim
清理缓存
yum clean all
yum clean all
创建缓存
yum makecache
yum makecache
综合案例:安装apache服务器,部署网站
1)卸载httpd
yum remove -y httpd
2)安装httpd
yum install -y httpd
3)启动httpd服务
systemctl start httpd
systemctl status httpd
4)测试首页
curl localhost
5)关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
6)浏览器地址输入
http://虚拟机的IP地址
7)AI生成HTML代码,复制
8)进入html目录,粘贴代码
cd /var/www/html
vim index.html
进入粘贴模式 :set paste回车
按i进入编辑模式,粘贴代码,保存
9)重启httpd
systemctl restart httpd
10)刷新浏览器
http://虚拟机的IP地址
yum remove -y httpd
2)安装httpd
yum install -y httpd
3)启动httpd服务
systemctl start httpd
systemctl status httpd
4)测试首页
curl localhost
5)关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
6)浏览器地址输入
http://虚拟机的IP地址
7)AI生成HTML代码,复制
8)进入html目录,粘贴代码
cd /var/www/html
vim index.html
进入粘贴模式 :set paste回车
按i进入编辑模式,粘贴代码,保存
9)重启httpd
systemctl restart httpd
10)刷新浏览器
http://虚拟机的IP地址
Shell编程
Shell入门
Shell是什么
Shell是一种解释器,将Linux命令解释为Linux内核能够执行的指令
同时也是一种编程语言,包含变量、分支、循环各种语法
同时也是一种编程语言,包含变量、分支、循环各种语法
Shell能做什么
Shell能将各种Linux指令编写成脚本,能够自动运行,实现自动化运维
Shell解释器
解释器分为:
/bin/bash 默认,用的最多
/bin/sh 更早的版本
perl
python
c
/bin/bash 默认,用的最多
/bin/sh 更早的版本
perl
python
c
显示当前的解释器
echo $SHELL
系统支持的解释器
cat /etc/shells
切换解释器
chsh -s 解释器
chsh -s /bin/sh
Shell脚本
命名规则
1)以.sh结尾
2)文件名以字母数字下划线组成,有意义的单词组成,如:install_httpd.sh
3)不要有特殊符号 % $ &等
2)文件名以字母数字下划线组成,有意义的单词组成,如:install_httpd.sh
3)不要有特殊符号 % $ &等
执行脚本的方式
1)./脚本 (必须有执行权限)
2). 脚本 (必须有执行权限)
3)完整路径/脚本 (必须有执行权限)
4)sh 脚本 (不需要有执行权限)
5)bash 脚本 (不需要有执行权限)
6)source 脚本 (不需要有执行权限)
2). 脚本 (必须有执行权限)
3)完整路径/脚本 (必须有执行权限)
4)sh 脚本 (不需要有执行权限)
5)bash 脚本 (不需要有执行权限)
6)source 脚本 (不需要有执行权限)
第一个Shell脚本
1)创建脚本文件
cd /opt
vim hello.sh
2)首行添加:
#!/bin/bash
指定脚本解释器
3)添加代码
# 输出一行文字
echo "Hello World!"
4)添加执行权限
chmod u+x hello.sh
5)运行
./hello.sh
cd /opt
vim hello.sh
2)首行添加:
#!/bin/bash
指定脚本解释器
3)添加代码
# 输出一行文字
echo "Hello World!"
4)添加执行权限
chmod u+x hello.sh
5)运行
./hello.sh
自动化部署网站
1)在目录中创建网页文件,粘贴网站
cd /opt
vim index.html 粘贴模式粘贴代码
2)编写脚本
vim install_httpd.sh
代码:
1 #!/bin/bash
2 #卸载httpd,安装httpd
3 yum remove -y httpd
4 yum install -y httpd
5 #启动httpd
6 systemctl start httpd
7 #防火墙关闭
8 systemctl stop firewalld
9 #复制网页到httpd的目录
10 cp index.html /var/www/html/index.html
11 #重启httpd
12 systemctl restart httpd
3)运行
chmod u+x install_httpd.sh
./install_httpd.sh
cd /opt
vim index.html 粘贴模式粘贴代码
2)编写脚本
vim install_httpd.sh
代码:
1 #!/bin/bash
2 #卸载httpd,安装httpd
3 yum remove -y httpd
4 yum install -y httpd
5 #启动httpd
6 systemctl start httpd
7 #防火墙关闭
8 systemctl stop firewalld
9 #复制网页到httpd的目录
10 cp index.html /var/www/html/index.html
11 #重启httpd
12 systemctl restart httpd
3)运行
chmod u+x install_httpd.sh
./install_httpd.sh
Shell的变量
变量是什么
变量是程序中内存空间,可以存在不同的数据
变量的命名规则
由字母、数字、下划线和$组成
不能由数字开头
不能是命令或关键字
要由有意义的单词组成,如:goods_price
不能由数字开头
不能是命令或关键字
要由有意义的单词组成,如:goods_price
自定义变量
开发者自己定义的变量,用于完成特定业务
定义变量
变量名=值
如:
name="张三"
age=20
使用变量
$变量
${变量}
减少变量使用的歧义
${变量}
减少变量使用的歧义
如:
echo $name
echo ${name}
输出:张三_20_宜昌
echo $name_$age_$address 存在问题,改为:
echo ${name}_${age}_${address}
echo $name_$age_$address 存在问题,改为:
echo ${name}_${age}_${address}
环境变量
自定义变量属于局部变量,只能在当前的Shell进程中使用,环境变量属于全局变量,所有Shell进程都可以访问
系统再带的环境变量
$SHELL 当前SHELL解释器
$PATH 程序路径
$LANG 语言
$RANDOM 随机数
$SHELL 当前SHELL解释器
$PATH 程序路径
$LANG 语言
$RANDOM 随机数
定义环境变量
export 变量=值
使用环境变量
和普通变量相同 $变量名 或 ${变量名}
案例:普通变量和环境变量的区别
在命令行,定义普通变量和环境变量
a=100
export b=200
创建脚本 vim test1.sh
#!/bin/bash
echo "a=$a b=$b"
添加执行权限
chmod u+x test1.sh
./test1.sh
在命令行,定义普通变量和环境变量
a=100
export b=200
创建脚本 vim test1.sh
#!/bin/bash
echo "a=$a b=$b"
添加执行权限
chmod u+x test1.sh
./test1.sh
位置变量
使用脚本时,可以向脚本传入参数,位置变量可以获取传入的参数
用法
$n n是数字,$1 代表第1参数
$@ 代表所有参数
$# 代表参数的数量
$0 代表文件名
$@ 代表所有参数
$# 代表参数的数量
$0 代表文件名
案例:
vim test2.sh
特殊变量
$?
上一个命令执行的结果
0 成功 >0 失败
0 成功 >0 失败
$$
当前Shell进程的进程号
$!
上一个后台进程的进程号
特殊符号
"双引号"
弱引用,在字符串中输出变量的值
"a=$a" ---> a=100
"a=$a" ---> a=100
'单引号'
强引用,字符串会原样输出
'a=$a' ---> a=$a
'a=$a' ---> a=$a
`反引号`
可以执行命令,将命令的结果赋值给变量
a=`ls -l | wc -l`
a=`ls -l | wc -l`
$()
和反引号作用相同,不容易出现混淆
a=$(ls -l | wc -l)
a=$(ls -l | wc -l)
$(())
变量进行运算
a=1 b=2 c=$((a+b))
a=1 b=2 c=$((a+b))
只读变量
定义后不能修改的变量
readonly 变量=值
readonly pi=3.14
pi=3.15
pi=3.15
变量输入
read 选项 变量名
选项:-p "提示文字"
选项:-p "提示文字"
示例:
read -p "请输入账号" username
read -p "请输入密码" password
echo $username $password
read -p "请输入账号" username
read -p "请输入密码" password
echo $username $password
案例:完成脚本,在脚本中输入两个变量的值,交换两个变量
read -p "输入第一个变量的值:" num1
read -p "输入第二个变量的值:" num2
echo "交换前:$num1 $num2"
tmp=$num1
num1=$num2
num2=$tmp
echo "交换后:$num1 $num2"
read -p "输入第一个变量的值:" num1
read -p "输入第二个变量的值:" num2
echo "交换前:$num1 $num2"
tmp=$num1
num1=$num2
num2=$tmp
echo "交换后:$num1 $num2"
Shell的运算符
运算符表达式
((表达式1,表达式2,.....))
可以包含多个表达式,从左向右执行,引用变量不加$
可以包含多个表达式,从左向右执行,引用变量不加$
如:((a=1,b=2,c=a+b))
[ 表达式 ]
包含一个表达式,引用变量要加$
包含一个表达式,引用变量要加$
expr 表达式
包含一个表达式,引用变量要加$,运算符两边要加空格
包含一个表达式,引用变量要加$,运算符两边要加空格
算术运算符
执行数学运算的符号,有:+、-、*、/、%、**、++、--
基本的算术运算
read -p "请输入第一个数:" num1
read -p "请输入第二个数:" num2
echo "$num1 + $num2 = $((num1+num2))"
echo "$num1 - $num2 = $((num1-num2))"
echo "$num1 * $num2 = $((num1*num2))"
echo "$num1 / $num2 = $((num1/num2))"
echo "$num1 % $num2 = $((num1%num2))"
echo "$num1 ** $num2 = $((num1**num2))"
read -p "请输入第一个数:" num1
read -p "请输入第二个数:" num2
echo "$num1 + $num2 = $((num1+num2))"
echo "$num1 - $num2 = $((num1-num2))"
echo "$num1 * $num2 = $((num1*num2))"
echo "$num1 / $num2 = $((num1/num2))"
echo "$num1 % $num2 = $((num1%num2))"
echo "$num1 ** $num2 = $((num1**num2))"
自增自减运算
属于一元运算符
变量++
变量--
变量++
变量--
变量++ 后缀
++变量 前缀
++变量 前缀
没有和其他运算一起执行,前缀和后缀没有区别
有其他运算一起执行,前缀是先执行自增或自减,再执行其他运算,后缀是先执行其他运算,再执行自增或自减
优先级
11+9-8*4/3%5**2=?
++ -- > ** > * / % > + -
11+9-8*4/3%5**2=?
++ -- > ** > * / % > + -
赋值运算符
将表达式的值保存到变量中
变量=表达式
从右到左运算,计算右边表达式的值,存入左边的变量
符合赋值运算符,结合算术运算符和赋值运算,有:
+=、-=、*=、/=、%=
a+=5 相当于 a=a+5
+=、-=、*=、/=、%=
a+=5 相当于 a=a+5
思考题:((a=10,a+=5,a-=3,a*=2,a/=4,a%=3))
关系运算符
用于比较两个数值的大小,结果是真(1)或假(0)
-eq 相等,相当于==,[ $a -eq 10 ]
-ne 不相等,相当于!=,[ $a -ne 10 ]
-gt 大于 ,相当于 >
-lt 小于,相当于 <
-ge 大于等于,相当于>=
-le 小于等于,相当于<=
-ne 不相等,相当于!=,[ $a -ne 10 ]
-gt 大于 ,相当于 >
-lt 小于,相当于 <
-ge 大于等于,相当于>=
-le 小于等于,相当于<=
字符串的比较
相等 = [ $name = "张三" ]
不相等 != [ $name != "张三" ]
为空 -z [ -z $name ]
不为空 -n [ -n $name ]
不相等 != [ $name != "张三" ]
为空 -z [ -z $name ]
不为空 -n [ -n $name ]
逻辑运算符
1)与 -a [ 条件1 -a 条件2 ] 两个条件必须同时成立,结果为真,否则为假
2)或 -o [ 条件1 -o 条件2 ] 两个条件有一个成立,结果为真,否则为假
3)非 -n [ -n 条件 ] 条件取反,真变假,假变真
2)或 -o [ 条件1 -o 条件2 ] 两个条件有一个成立,结果为真,否则为假
3)非 -n [ -n 条件 ] 条件取反,真变假,假变真
文件测试运算符
-e 判断文件是否存在 [ -e $file ]
-f 判断是否是普通文件 [ -f $file ]
-d 判断是否是目录
-l 判断是否是链接
-b 判断是否是块文件
-x 判断是否有执行权限
-w 判断是否有写权限
-r 判断是否有读权限
-f 判断是否是普通文件 [ -f $file ]
-d 判断是否是目录
-l 判断是否是链接
-b 判断是否是块文件
-x 判断是否有执行权限
-w 判断是否有写权限
-r 判断是否有读权限
分支语句
按条件进行判断,执行不同的语句
基本if语句
条件成立会执行if后的语句,不成立就不执行
if [ 条件 ]
then
语句
fi
then
语句
fi
if [ 条件 ];then
语句
fi
语句
fi
案例:输入人的年龄,判断是否成年人
read -p "请输入你的年龄" age
if [ $age -ge 18 ]
then
echo "你是成年人"
fi
read -p "请输入你的年龄" age
if [ $age -ge 18 ]
then
echo "你是成年人"
fi
if-else语句
条件成立会执行if后的语句,不成立会执行else后的语句
if [ 条件 ]
then
语句
else
语句
fi
then
语句
else
语句
fi
案例:输入人的年龄,判断是否成年人
read -p "请输入你的年龄" age
if [ $age -ge 18 ]
then
echo "你是成年人"
else
echo "你是未成年人"
fi
read -p "请输入你的年龄" age
if [ $age -ge 18 ]
then
echo "你是成年人"
else
echo "你是未成年人"
fi
案例:输入一个数,判断是奇数还是偶数
read -p "请输入一个数" num
if [ $[$num%2] -eq 0 ]
then
echo "$num是偶数"
else
echo "$num是奇数"
fi
read -p "请输入一个数" num
if [ $[$num%2] -eq 0 ]
then
echo "$num是偶数"
else
echo "$num是奇数"
fi
案例:输入年份,判断是否是闰年(年份能被400整除 或者 年份能被4整除并且不能被100整除)
read -p "请输入年份:" year
if [ $[$year%400] -eq 0 -o $[$year%4] -eq 0 -a $[$year%100] -ne 0 ]
then
echo "$year是闰年"
else
echo "$year不是闰年"
fi
read -p "请输入年份:" year
if [ $[$year%400] -eq 0 -o $[$year%4] -eq 0 -a $[$year%100] -ne 0 ]
then
echo "$year是闰年"
else
echo "$year不是闰年"
fi
案例:招公务员,条件是籍贯是宜昌,年龄小于等于40岁
read -p "请输入籍贯" addr
read -p "请输入年龄" age
if [ -z $addr ]
then
echo "籍贯不能为空"
exit
fi
if [ -z $age ]
then
echo "年龄不能为空"
exit
fi
if [ $addr = "宜昌" -a $age -le 40 ]
then
echo "你可以报名"
else
echo "你没有报名资格"
fi
read -p "请输入籍贯" addr
read -p "请输入年龄" age
if [ -z $addr ]
then
echo "籍贯不能为空"
exit
fi
if [ -z $age ]
then
echo "年龄不能为空"
exit
fi
if [ $addr = "宜昌" -a $age -le 40 ]
then
echo "你可以报名"
else
echo "你没有报名资格"
fi
多重if语句
可以判断多个条件,依次判断条件,有一个成立就执行后面的语句,执行后结束
if [ 条件1 ]
then
语句
elif [ 条件2 ]
then
语句
else
语句
fi
then
语句
elif [ 条件2 ]
then
语句
else
语句
fi
案例:输入你的成绩,判断出优良中差
read -p "请输入你的成绩:" score
if [ $score -ge 90 ]
then
echo "你的成绩是优秀"
elif [ $score -ge 80 ]
then
echo "你的成绩是良好"
elif [ $score -ge 60 ]
then
echo "你的成绩是中等"
else
echo "你的成绩是较差"
fi
read -p "请输入你的成绩:" score
if [ $score -ge 90 ]
then
echo "你的成绩是优秀"
elif [ $score -ge 80 ]
then
echo "你的成绩是良好"
elif [ $score -ge 60 ]
then
echo "你的成绩是中等"
else
echo "你的成绩是较差"
fi
案例:输入两个数,输出两个数的大小关系
read -p "请输入第一个数:" num1
read -p "请输入第二个数:" num2
if [ $num1 -gt $num2 ]
then
echo "$num1大于$num2"
elif [ $num1 -lt $num2 ]
then
echo "$num1小于$num2"
else
echo "$num1等于$num2"
fi
read -p "请输入第一个数:" num1
read -p "请输入第二个数:" num2
if [ $num1 -gt $num2 ]
then
echo "$num1大于$num2"
elif [ $num1 -lt $num2 ]
then
echo "$num1小于$num2"
else
echo "$num1等于$num2"
fi
案例:输入一个文件路径,判断其是普通文件还是目录还是其他类型的文件,如果是普通文件,则判断是否有写权限,有的话就往文件写入一段文字
read -p "请输入一个文件路径" file
if [ -e $file ]
then
echo "$file文件存在"
else
echo "$file不存在"
exit
fi
if [ -f $file ]
then
echo "$file是普通文件"
if [ -w $file ]
then
echo "hello" >> $file
cat $file
fi
elif [ -d $file ]
then
echo "$file是目录"
else
echo "$file是其他类型文件"
fi
read -p "请输入一个文件路径" file
if [ -e $file ]
then
echo "$file文件存在"
else
echo "$file不存在"
exit
fi
if [ -f $file ]
then
echo "$file是普通文件"
if [ -w $file ]
then
echo "hello" >> $file
cat $file
fi
elif [ -d $file ]
then
echo "$file是目录"
else
echo "$file是其他类型文件"
fi
案例:输入一个用户名,判断该用户是否存在,如果不存在则创建该用户,并为其设置密码
read -p "请输入用户名:" username
id $username &> /dev/null
if [ $? -eq 0 ]
then
echo "$username已经存在"
else
echo "创建$username"
useradd $username
echo "123" | passwd $username --stdin
fi
read -p "请输入用户名:" username
id $username &> /dev/null
if [ $? -eq 0 ]
then
echo "$username已经存在"
else
echo "创建$username"
useradd $username
echo "123" | passwd $username --stdin
fi
case语句
判断表达式的值,如果值能够匹配上,就执行该值后面的语句
case 变量表达式 in
值1 )
语句1
;;
值2 )
语句2
;;
* )
缺省语句
;;
esac
值1 )
语句1
;;
值2 )
语句2
;;
* )
缺省语句
;;
esac
案例:向脚本传入三个参数:数字1 数字2 运算符
判断运算符执行算术运算
case $3 in
"+" )
echo "$1 + $2 = $(($1+$2))"
;;
"-" )
echo "$1 - $2 = $(($1-$2))"
;;
"*" )
echo "$1 * $2 = $(($1*$2))"
;;
"/" )
echo "$1 / $2 = $(($1/$2))"
;;
"%" )
echo "$1 % $2 = $(($1%$2))"
;;
"**" )
echo "$1 ** $2 = $(($1**$2))"
;;
* )
echo "运算符错误"
;;
esac
判断运算符执行算术运算
case $3 in
"+" )
echo "$1 + $2 = $(($1+$2))"
;;
"-" )
echo "$1 - $2 = $(($1-$2))"
;;
"*" )
echo "$1 * $2 = $(($1*$2))"
;;
"/" )
echo "$1 / $2 = $(($1/$2))"
;;
"%" )
echo "$1 % $2 = $(($1%$2))"
;;
"**" )
echo "$1 ** $2 = $(($1**$2))"
;;
* )
echo "运算符错误"
;;
esac
循环语句
for循环
固定次数循环
循环三个要素:变量初始化,循环条件,变量更新
for ((变量=值;循环条件;变量更新))
do
语句
done
do
语句
done
案例:循环10次
for ((i=1;i<=10;i++))
do
echo "i=$i"
done
for ((i=1;i<=10;i++))
do
echo "i=$i"
done
遍历式循环
可以用于依次访问多个数据(数组,序列..)
for 变量 in $数组 或 序列
do
语句
done
do
语句
done
案例:循环10次
for i in {1..10}
do
echo "i=$i"
done
案例:遍历任意多个数
for i in 44 33 88 66 99
do
echo "i=$i"
done
案例:脚本传入多个参数,将多个参数值求和
sum=0
for i in $@
do
((sum+=i))
done
echo "参数的和是: $sum"
案例:遍历/opt目录所有文件名
files=$(ls /opt)
for f in $files
do
echo "文件有:$f"
done
for i in {1..10}
do
echo "i=$i"
done
案例:遍历任意多个数
for i in 44 33 88 66 99
do
echo "i=$i"
done
案例:脚本传入多个参数,将多个参数值求和
sum=0
for i in $@
do
((sum+=i))
done
echo "参数的和是: $sum"
案例:遍历/opt目录所有文件名
files=$(ls /opt)
for f in $files
do
echo "文件有:$f"
done
while循环
先判断循环条件,如果成立就执行循环,不成立就结束循环
while [ 条件 ] ---> while (( 条件 ))
do
语句
done
do
语句
done
案例:循环输出1~10
i=1
while [ $i -le 10 ]
do
echo "i = $i"
((i++))
done
i=1
while [ $i -le 10 ]
do
echo "i = $i"
((i++))
done
案例:假设一张纸是1毫米,问对折多少次后能达到珠峰高度8848米
i=1
count=0
while [ $i -le 8848000 ]
do
((i*=2))
((count++))
done
echo "对折$count次"
i=1
count=0
while [ $i -le 8848000 ]
do
((i*=2))
((count++))
done
echo "对折$count次"
until循环
先判断循环条件,条件成立就结束循环,否则就执行循环
until [ 条件 ]
do
语句
done
do
语句
done
案例:输出1~10
i=1
until [ $i -gt 10 ]
do
echo "i = $i"
((i++))
done
i=1
until [ $i -gt 10 ]
do
echo "i = $i"
((i++))
done
案例:打印20个斐波拉契数列:1 1 2 3 5 8 13 21 34 55 ....
n1=1
n2=1
echo -n "$n1 $n2 "
count=0
until [ $count -ge 9 ]
do
((n1=n1+n2))
((n2=n1+n2))
echo -n "$n1 $n2 "
((count++))
done
n1=1
n2=1
echo -n "$n1 $n2 "
count=0
until [ $count -ge 9 ]
do
((n1=n1+n2))
((n2=n1+n2))
echo -n "$n1 $n2 "
((count++))
done
循环控制
在循环过程中,通过条件判断来决定是否结束循环,或跳过本次循环
break
结束循环
案例:上班365天,到100天中大奖,跟老板提出辞职
for((i=1;i<=365;i++))
do
if [ $i -eq 100 ]
then
echo "哇!我中了大奖!小王,以后我不去了!"
break
fi
echo "我上了$i天班"
done
for((i=1;i<=365;i++))
do
if [ $i -eq 100 ]
then
echo "哇!我中了大奖!小王,以后我不去了!"
break
fi
echo "我上了$i天班"
done
continue
跳过本次循环,执行下一次
案例:上班365天,到100天骑车摔了,跟老板请假一天
for((i=1;i<=365;i++))
do
if [ $i -eq 100 ]
then
echo "哇!前面有个坑!王老板,我摔了,今天能不能请个假?"
continue
fi
echo "我上了$i天班"
done
for((i=1;i<=365;i++))
do
if [ $i -eq 100 ]
then
echo "哇!前面有个坑!王老板,我摔了,今天能不能请个假?"
continue
fi
echo "我上了$i天班"
done
案例:开发抽奖游戏,产生1~100的随机数,给5次机会输入数,数字比随机数大或小要进行提示,如果相等就提示中奖并结束循环
rand=$(($RANDOM%100+1))
for((i=1;i<=5;i++))
do
read -p "请输入一个数: " num
if [ $num -gt $rand ]
then
echo "你猜大了"
elif [ $num -lt $rand ]
then
echo "你猜小了"
else
echo "恭喜你,中奖了!"
break
fi
done
rand=$(($RANDOM%100+1))
for((i=1;i<=5;i++))
do
read -p "请输入一个数: " num
if [ $num -gt $rand ]
then
echo "你猜大了"
elif [ $num -lt $rand ]
then
echo "你猜小了"
else
echo "恭喜你,中奖了!"
break
fi
done
嵌套循环
在循环内部可以完整嵌套另一个循环,外部循环每执行一次,内部循环会执行一轮
for
for
while
while
for
while
while
案例:打印矩形(内部循环输出多个*,外部循环控制打印行数)
# 外层循环控制行数
for((i=1;i<=4;i++))
do
# 内层循环控制*数
for((j=1;j<=5;j++))
do
echo -n "* "
done
# 输出换行
echo ""
done
改进:将行数和列数改为参数控制 $1 $2
# 外层循环控制行数
for((i=1;i<=4;i++))
do
# 内层循环控制*数
for((j=1;j<=5;j++))
do
echo -n "* "
done
# 输出换行
echo ""
done
改进:将行数和列数改为参数控制 $1 $2
案例:打印正三角型
*
* *
* * *
* * * *
for((i=1;i<=4;i++))
do
for((j=1;j<=i;j++))
do
echo -n "* "
done
echo ""
done
*
* *
* * *
* * * *
for((i=1;i<=4;i++))
do
for((j=1;j<=i;j++))
do
echo -n "* "
done
echo ""
done
案例:等腰三角形
* 1 3空(4-行) 1*(2*行-1)
* * * 2 2空 3*
* * * * * 3 1空 5*
* * * * * * * 4 0空 7*
for((i=1;i<=4;i++))
do
for((j=1;j<=$((4-i));j++))
do
echo -n " "
done
for((k=1;k<=$((2*i-1));k++))
do
echo -n "* "
done
echo ""
done
* 1 3空(4-行) 1*(2*行-1)
* * * 2 2空 3*
* * * * * 3 1空 5*
* * * * * * * 4 0空 7*
for((i=1;i<=4;i++))
do
for((j=1;j<=$((4-i));j++))
do
echo -n " "
done
for((k=1;k<=$((2*i-1));k++))
do
echo -n "* "
done
echo ""
done
数组
可以同时保存多个数据,方便运算
定义数组
数组名=(值1 值2 值3 )
如:names=("张三" "李四" "万五")
如:names=("张三" "李四" "万五")
访问数组
数组元素通过下标来访问的,下标从0开始
修改数组元素
数组名[下标]=值
如:names[0]="刘备"
如:names[0]="刘备"
访问数组元素
${数组名[下标]}
如:echo ${names[0]} ${names[1]} ${names[2]}
如:echo ${names[0]} ${names[1]} ${names[2]}
访问所有元素
${数组名[@]}
如:echo ${names[@]}
如:echo ${names[@]}
访问数组长度
${#数组名[@]}
如:echo ${#names[@]}
如:echo ${#names[@]}
截取数组
${数组名[@]:开始下标:长度}
如:
echo "前三位是:${names[@]:0:3}"
echo "后三位是:${names[@]:3:3}"
如:
echo "前三位是:${names[@]:0:3}"
echo "后三位是:${names[@]:3:3}"
遍历数组
常规for循环
案例:
names=("张三" "李四" "王五" "赵六")
#获得数组的长度
len=${#names[@]}
for((i=0;i<len;i++))
do
echo "第$((i+1))人是:${names[$i]}
done
names=("张三" "李四" "王五" "赵六")
#获得数组的长度
len=${#names[@]}
for((i=0;i<len;i++))
do
echo "第$((i+1))人是:${names[$i]}
done
for-in循环
案例:
nums=(77 88 99 102 802 622)
for n in ${nums[@]}
do
echo "num=${n}"
done
nums=(77 88 99 102 802 622)
for n in ${nums[@]}
do
echo "num=${n}"
done
相关案例
1)输入5个同学的成绩,计算总分和平均分
scores=()
len=5
sum=0
for((i=0;i<len;i++))
do
read -p "请输入第$((i+1))个同学成绩:" scores[$i]
sum=$[$sum+${scores[$i]}]
done
echo "总成绩是:$sum,平均分是:$((sum/len))"
scores=()
len=5
sum=0
for((i=0;i<len;i++))
do
read -p "请输入第$((i+1))个同学成绩:" scores[$i]
sum=$[$sum+${scores[$i]}]
done
echo "总成绩是:$sum,平均分是:$((sum/len))"
2)输入8个人的姓名,输入要查找的姓名,查找该人是否存在
names=()
len=8
for((i=0;i<len;i++))
do
read -p "请输入第$((i+1))个人的姓名:" names[$i]
done
read -p "请输入你要找的姓名:" name
pos=-1
for((i=0;i<len;i++))
do
echo "$name ${names[$i]}"
if [ $name = ${names[$i]} ]
then
pos=$i
break
fi
done
if [ $pos -eq -1 ]
then
echo "没有找到这个人"
else
echo "此人是第$((pos+1))个人"
fi
names=()
len=8
for((i=0;i<len;i++))
do
read -p "请输入第$((i+1))个人的姓名:" names[$i]
done
read -p "请输入你要找的姓名:" name
pos=-1
for((i=0;i<len;i++))
do
echo "$name ${names[$i]}"
if [ $name = ${names[$i]} ]
then
pos=$i
break
fi
done
if [ $pos -eq -1 ]
then
echo "没有找到这个人"
else
echo "此人是第$((pos+1))个人"
fi
3)输入5个数字,进行冒泡排序
nums=()
len=5
for((i=0;i<len;i++))
do
read -p "请输入第$((i+1))个数:" nums[$i]
done
# 外层循环控制比较轮数
for((i=0;i<$[$len-1];i++))
do
# 内层循环控制两两比较
for((j=0;j<$[$len-1-$i];j++))
do
# 前一个数比后一个数大,就交换
if [ ${nums[$j]} -gt ${nums[$[$j+1]]} ]
then
temp=${nums[$j]}
nums[$j]=${nums[$[$j+1]]}
nums[$[$j+1]]=$temp
fi
done
done
# 输出排序后结果
for n in ${nums[@]}
do
echo $n
done
nums=()
len=5
for((i=0;i<len;i++))
do
read -p "请输入第$((i+1))个数:" nums[$i]
done
# 外层循环控制比较轮数
for((i=0;i<$[$len-1];i++))
do
# 内层循环控制两两比较
for((j=0;j<$[$len-1-$i];j++))
do
# 前一个数比后一个数大,就交换
if [ ${nums[$j]} -gt ${nums[$[$j+1]]} ]
then
temp=${nums[$j]}
nums[$j]=${nums[$[$j+1]]}
nums[$[$j+1]]=$temp
fi
done
done
# 输出排序后结果
for n in ${nums[@]}
do
echo $n
done
文件三剑客
1)grep 文件内容的过滤
2)sed 按行查找并编辑文件内容
3)awk 按列处理文件,支持流程控制
2)sed 按行查找并编辑文件内容
3)awk 按列处理文件,支持流程控制
GREP命令
对文件内容进行过滤,支持正则表达式
语法
grep 选项 "内容" 文件路径
示例:
grep "root" /etc/passwd
grep "root" /etc/passwd
选项
-i 表示忽略过滤信息的大小写
-o 表示只显示匹配到内容
-n 表示过滤信息显示输出行号
-c 表示统计过滤信息的次数
-v 表示对过滤信息进行取反显示
-e 表示多个条件过滤文件
-E 等价于egrep命令,识别扩展正则表达式
-m n 表示匹配前n次后停止匹配
-B n 表示过滤的信息和过滤信息前n行信息一起过滤输出
-A n 表示过滤的信息和过滤信息后n行信息一起过滤输出
-C n 表示过滤的信息和过滤信息前后n行信息一起过滤输出
-i 表示忽略过滤信息的大小写
-o 表示只显示匹配到内容
-n 表示过滤信息显示输出行号
-c 表示统计过滤信息的次数
-v 表示对过滤信息进行取反显示
-e 表示多个条件过滤文件
-E 等价于egrep命令,识别扩展正则表达式
-m n 表示匹配前n次后停止匹配
-B n 表示过滤的信息和过滤信息前n行信息一起过滤输出
-A n 表示过滤的信息和过滤信息后n行信息一起过滤输出
-C n 表示过滤的信息和过滤信息前后n行信息一起过滤输出
案例:
1)忽略大小写,查找root
grep -i "Root" /etc/passwd
1)忽略大小写,查找root
grep -i "Root" /etc/passwd
2)只显示匹配的内容
grep -o "root" /etc/passwd
grep -o "root" /etc/passwd
3)显示行号
grep -o -n "root" /etc/passwd
grep -o -n "root" /etc/passwd
4)统计root出现的行数
grep -c "root" /etc/password
grep -c "root" /etc/password
正则表达式
一些特殊文字符号,能够组合更灵活匹配的匹配字符串
元字符
. 任意字符
[ ] 匹配范围
[0-9] 数字
[a-z] 小写字母
[A-Z] 大写字母
[abc] abc中任意一个
[^abc] 不是abc的任意字符
[a-zA-Z0-9] 任意的字母或数字
[ ] 匹配范围
[0-9] 数字
[a-z] 小写字母
[A-Z] 大写字母
[abc] abc中任意一个
[^abc] 不是abc的任意字符
[a-zA-Z0-9] 任意的字母或数字
案例
1)找passwd文件中所有的数字
grep "[0-9]" /etc/passwd
1)找passwd文件中所有的数字
grep "[0-9]" /etc/passwd
位置匹配
^ 匹配开头
$ 匹配结尾
$ 匹配结尾
案例
1)查找root开头的文字
grep "^root" /etc/passwd
2)查找login结尾的文字
grep "login$" /etc/passwd
3)匹配完整的hello world文字
grep "^hello world$" test
4)匹配hello开头的world结尾的文字
grep "^hello.*world$" test
grep "^root" /etc/passwd
2)查找login结尾的文字
grep "login$" /etc/passwd
3)匹配完整的hello world文字
grep "^hello world$" test
4)匹配hello开头的world结尾的文字
grep "^hello.*world$" test
次数匹配
* 匹配任意长度
以下符号属于扩展正则表达式
+ 匹配一次以上
? 匹配0次或1次
{n} 匹配n次
{n,m} 匹配n到m次数
{n,} 匹配至少n次
{,n} 匹配最多n次
以下符号属于扩展正则表达式
+ 匹配一次以上
? 匹配0次或1次
{n} 匹配n次
{n,m} 匹配n到m次数
{n,} 匹配至少n次
{,n} 匹配最多n次
案例
1)匹配网址 www开头 .com结尾 中间有任意多文字
grep "^www\.[a-zA-Z0-9]*\.com$" test.txt
2)匹配正整数
grep -E "^\+?[0-9]+$" test.txt
3)匹配4位数字
grep -E "^[0-9]{4}$" test.txt
4)匹配4到6位数字
grep -E "^[0-9]{4,6}$" test.txt
5)匹配3位以上数字
grep -E "^[0-9]{3,}$" test.txt
6)匹配手机号 11位数字 第1位是1 第二位是3~9
grep -E "^1[3-9][0-9]{9}$" test.txt
grep "^www\.[a-zA-Z0-9]*\.com$" test.txt
2)匹配正整数
grep -E "^\+?[0-9]+$" test.txt
3)匹配4位数字
grep -E "^[0-9]{4}$" test.txt
4)匹配4到6位数字
grep -E "^[0-9]{4,6}$" test.txt
5)匹配3位以上数字
grep -E "^[0-9]{3,}$" test.txt
6)匹配手机号 11位数字 第1位是1 第二位是3~9
grep -E "^1[3-9][0-9]{9}$" test.txt
分组
将一系列字符作为整体进行匹配
匹配两个good
good{2} ---> goodd
(good){2} ----> goodgood
匹配两个good
good{2} ---> goodd
(good){2} ----> goodgood
案例
1)匹配连续的两个hello
grep -E "(hello){2}" test.txt
2)查找一个hello或world
egrep -e "hello" -e "world" test.txt
egrep "(hello|world)" test.txt
3)查找连续的两个三位字母和三位数字 abc454gaw454
egrep ""
grep -E "(hello){2}" test.txt
2)查找一个hello或world
egrep -e "hello" -e "world" test.txt
egrep "(hello|world)" test.txt
3)查找连续的两个三位字母和三位数字 abc454gaw454
egrep ""
SED命令
流编辑器,按行对文件内容进行处理(增删改查
用法 : sed 选项 "操作" 文件路径
选项
-n 关闭sed默认的输出
-r 识别扩展正则表达式
-i 可以修改原始文件
-r 识别扩展正则表达式
-i 可以修改原始文件
操作
p 打印
c 替换
s 查找+替换
d 删除
i 插入
a 追加
w 写入文件
r 读取文件
c 替换
s 查找+替换
d 删除
i 插入
a 追加
w 写入文件
r 读取文件
案例
按行查找
1)输出文件内容
sed -n "p" test.txt
2)输出文件的第5行
sed -n "5p" test.txt
3)输出文件的5到10行
sed -n "5,10p" test.txt
4)输出5到最后一行
sed -n "5,\$p" test.txt
sed -n '5,$p' test.txt
5)打印第6到后面3行
sed -n '6,+3p' test.txt
6)打印奇数行(设置步长 开始行数~步长)
sed -n '1~2p' test.txt
sed -n "p" test.txt
2)输出文件的第5行
sed -n "5p" test.txt
3)输出文件的5到10行
sed -n "5,10p" test.txt
4)输出5到最后一行
sed -n "5,\$p" test.txt
sed -n '5,$p' test.txt
5)打印第6到后面3行
sed -n '6,+3p' test.txt
6)打印奇数行(设置步长 开始行数~步长)
sed -n '1~2p' test.txt
正则表达式查找
1)查找以hello开头的行
sed -n '/^hello/p' test.txt
2)打印第二行到以hello开头的行
sed -n '2,/^hello/p' test.txt
3)从hello开头的行打印到world结尾行
sed -n '/^hello/,/world$/p' test.txt
sed -n '/^hello/p' test.txt
2)打印第二行到以hello开头的行
sed -n '2,/^hello/p' test.txt
3)从hello开头的行打印到world结尾行
sed -n '/^hello/,/world$/p' test.txt
替换
替换整行
行号或正则表达式c替换的内容
案例
1)把第三行改为--------------------------
sed "3c--------------------------" test.txt
默认sed不改原始文件,必须加-i
sed -i "3c--------------------------" test.txt
2)修改原始文件同时对文件进行备份 -i.后缀名
sed -i.bak "5c===================" test.txt
sed "3c--------------------------" test.txt
默认sed不改原始文件,必须加-i
sed -i "3c--------------------------" test.txt
2)修改原始文件同时对文件进行备份 -i.后缀名
sed -i.bak "5c===================" test.txt
查找和替换
s/搜索的内容/替换的内容/g g全局替换,默认只替换第一个
s#搜索的内容#替换的内容#g
s#搜索的内容#替换的内容#g
案例
1)将文件中的hello替换为nice
sed -i "s/hello/nice/g" test.txt
2)修改网络配置文件
cp /etc/sysconfig/network-scripts/ifcfg-ens33 /opt/ip.txt
sed -i -r 's/^IPADDR=([0-9]{1,3}\.){3}[0-9]{1,3}$/IPADDR=192.168.101.188/g' ip.txt
sed -i "s/hello/nice/g" test.txt
2)修改网络配置文件
cp /etc/sysconfig/network-scripts/ifcfg-ens33 /opt/ip.txt
sed -i -r 's/^IPADDR=([0-9]{1,3}\.){3}[0-9]{1,3}$/IPADDR=192.168.101.188/g' ip.txt
删除
1)删除第三行
sed "3d" test.txt
2)删除3到5行
sed '3,5d' test.txt
3)删除hello开头的行
sed -i '/^hello/d' test.txt
sed "3d" test.txt
2)删除3到5行
sed '3,5d' test.txt
3)删除hello开头的行
sed -i '/^hello/d' test.txt
插入
1)在第三行的前面插入6666666666666
sed '3i6666666666666666' test.txt
2)在第5行后面插入***************************
sed '5a******************************' test.txt
3)在nice开头的行后面插入%%%%%%%%%%%%
sed '/^nice/a%%%%%%%%%%%%%%%%%%' test.txt
sed '3i6666666666666666' test.txt
2)在第5行后面插入***************************
sed '5a******************************' test.txt
3)在nice开头的行后面插入%%%%%%%%%%%%
sed '/^nice/a%%%%%%%%%%%%%%%%%%' test.txt
AWK命令
是一种脚本语言,支持按列对文件进行统计
用法: awk 选项 '脚本代码' 文件路径
选项
-F 用于设置分隔符,默认是空格
-v 用于定义变量
-f 用于指定脚本文件
-v 用于定义变量
-f 用于指定脚本文件
内置变量
FS 分隔符
NF 列数
NR 行数
NF 列数
NR 行数
案例
1)基本用法
awk -F: '{print $1,$3}' /etc/passwd
列引用方式:
$n 如:$1 第一列
$0 整行
$NF NF是列数 $NF 代表最后一列
awk -F: '{print $1,$3}' /etc/passwd
列引用方式:
$n 如:$1 第一列
$0 整行
$NF NF是列数 $NF 代表最后一列
2)取出本机IP地址
ifconfig | grep "broadcast" | awk '{print $2}'
ifconfig | grep "broadcast" | awk '{print $2}'
3)获得磁盘的利用率
df | sed -n '2,$p' | awk '{print $1,$5}' | sed 's/%//'
df | sed -n '2,$p' | awk '{print $1,$5}' | tr '%' ' '
df | sed -n '2,$p' | awk '{print $1,$5}' | sed 's/%//'
df | sed -n '2,$p' | awk '{print $1,$5}' | tr '%' ' '
4)控制打印格式
printf "格式字符串",值1,值2
%s 字符串 %20s 定义宽度
%d 整数
%f 小数
\n 换行
awk -F: '{printf "用户名是:%-20s 用户ID是:%d\n",$1,$3 }' /etc/passwd
printf "格式字符串",值1,值2
%s 字符串 %20s 定义宽度
%d 整数
%f 小数
\n 换行
awk -F: '{printf "用户名是:%-20s 用户ID是:%d\n",$1,$3 }' /etc/passwd
5)打印第5行的倒数第二列
awk -F: 'NR==5{print $(NF-1)}' /etc/passwd
打印第三行到第7行的第一列
awk -F: 'NR>=3&&NR<=7{print $1}' /etc/passwd
awk -F: 'NR==5{print $(NF-1)}' /etc/passwd
打印第三行到第7行的第一列
awk -F: 'NR>=3&&NR<=7{print $1}' /etc/passwd
6)打印所有的自定义用户(uid>=1000)
awk -F: '$3>=1000{print $1,$3}' /etc/passwd
awk -F: '$3>=1000{print $1,$3}' /etc/passwd
7)统计常规用户(/bin/bash)和虚拟用户的数量
BEGIN模式 操作文件前会执行一次
END模式 完成操作后会执行一次
awk -F: 'BEGIN{a=0;b=0}{if ($NF=="/bin/bash") {a++} else {b++}}END{printf "常规用户数:%d,虚拟用户数:%d\n",a,b}' /etc/passwd
BEGIN模式 操作文件前会执行一次
END模式 完成操作后会执行一次
awk -F: 'BEGIN{a=0;b=0}{if ($NF=="/bin/bash") {a++} else {b++}}END{printf "常规用户数:%d,虚拟用户数:%d\n",a,b}' /etc/passwd
0 条评论
下一页