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