当前位置: 首页 > web >正文

Linux 入门到精通,真的不用背命令!零基础小白靠「场景化学习法」,3 个月拿下运维 offer,第二十七天

shell脚本编程

六、流程控制

 条件选择
选择执行if语句
if结构:
[root@ansible-salve1 shell]# help if
if: if 条件; then 命令; [ elif 命令; then 命令; ]... [ else 命令; ] fi根据条件执行命令。`if COMMANDS'列表被执行。如果退出状态为零,则执行`then COMMANDS' 列表。否则按顺序执行每个 `elif COMMANDS'列表,并且如果它的退出状态为零,则执行对应的 `then COMMANDS' 列表并且 if 命令终止。否则如果存在的情况下,执行 `else COMMANDS'列表。整个结构的退出状态是最后一个执行的命令的状态,或者如果没有条件测试为真的话,为零。退出状态:返回最后一个执行的命令的状态。
[root@ansible-salve1 shell]# 
单分支
if [ 条件判断式 ];then命令
fi 
​
或者
​
if [ 条件判断式 ]then命令
fi
双分支
if [ 条件判断式 ]then命令
else命令
fi
多分支
if [ 条件判断式1 ]then命令
elif [ 条件判断式2 ]then 命令
...
...
else命令
fi
示例:依据BMI参数写出判断语句
[root@ansible-salve1 shell]# vim info5.sh
​
#!/bin/bash
read -p "请输入身高(m为单位):" HIGH
if [[ ! "$HIGH" =~ ^[0-2].?[0-9]{,2}$ ]]thenecho "请不要输入错误的身高";exit 1;
fi
read -p "请输入体重(Kg为单位):" WEIGHT
if [[ ! "$WEIGHT" =~ ^[0-9]{1,3}$ ]]thenecho "请不要输入错误的体重";exit 1;
fi
​
BMI=`echo $WEIGHT/$HIGH^2|bc` 
​
if [ $BMI -le 18 ] ;thenecho "你太瘦了,请注意身体建康"
elif [ $BMI -lt 24 ] ;thenecho "身材很棒!"
elseecho "你太胖了,注意节食,加强运动"
fi
​
[root@ansible-salve1 shell]# chmod +x info5.sh
[root@ansible-salve1 shell]# ./info5.sh

说明:

在面对多个if条件时,程序会依次对每个条件进行判断。一旦遇到第一个符合条件的“真”条件,就会执行相应的分支操作,并就此结束整个if语句。此外,if语句可以相互嵌套,从而实现更复杂的逻辑控制。

条件判断case语句

格式

[root@ansible-salve1 shell]# help case
case: case 词 in [模式 [| 模式]...) 命令 ;;]... esac基于模式匹配来执行命令。基于 PATTERN 模式匹配的词 WORD,有选择的执行 COMMANDS 命令。`|' 用于分隔多个模式。退出状态:返回最后一个执行的命令的状态。
[root@ansible-salve1 shell]# 
case 变量引用 in
PAT1)分支1;;
PAT2)分支2;;
...
*)默认分支;;
esac

case支持glob风格的通配符
*: 任意长度任意字符
?: 任意单个字符
[]: 指定范围内的任意单个字符
|: 或,如a|b ,a或b

示例:

[root@ansible-salve1 shell]# vim info6.sh 
#!/bin/bash
read -p "Do you agree(yes/no)?" INPUT
​
INPUT=`echo $INPUT | tr 'A-Z' 'a-z'`
​
case $INPUT in
y|yes)  echo "You input is Yes";;
n|no)echo "You input is No";;
*)      echo "Input fales,please input yes or no!"
esac  
[root@ansible-salve1 shell]# chmod +x info6.sh
[root@ansible-salve1 shell]# ./info6.sh 
Do you agree(yes/no)?yes
You input is Yes
[root@ansible-salve1 shell]# ./info6.sh 
Do you agree(yes/no)?no
You input is No
[root@ansible-salve1 shell]# ./info6.sh 
Do you agree(yes/no)?111
Input fales,please input yes or no!
[root@ansible-salve1 shell]# 
工作选项
[root@ansible-salve1 shell]# vim info7.sh
#!/bin/bash
cat <<EOF
请选择:
1.备份文件
2.清理日志文件
3.软件升级
4.软件回滚
5.删库跑路
EOF
read -p "请输入上面的数字1-5:" MENU
case $MENU in
1)./backup.sh;;
2)echo "清理日志";;
3)echo "软件升级";;
4)echo "软件回滚";;
5)echo "删库跑路";;
*)echo "Input False"
esac
[root@ansible-salve1 shell]# chmod +x info7.sh 
[root@ansible-salve1 shell]# ./info7.sh 
请选择:
1.备份数据库
2.清理日志文件
3.软件升级
4.软件回滚
5.删库跑路
请输入上面的数字1-5:1
备份成功
[root@ansible-salve1 shell]# 
循环
循环执行介绍

将特定的代码段重复执行多次通常涉及到循环结构,该结构包含进入循环的条件以及退出循环的条件。在某些情况下,循环需要执行的次数是预先知道的。然而,在其他情况下,循环的次数可能事先无法确定,这取决于程序运行时的具体条件。

常见的循环的命令:
for,while
for循环

格式1:

# 第一种写法
for NAME [in words ...]; do commands;done
​
# 第二种写法
for 变量 in 列表循环体
done
​
# 第三种写法
for 变量 in 列表
do循环体
done
执行机制:

依次将列表中的元素赋值给”变量名“;每次赋值后即执行一次循环体;直到列表中的元素耗尽,循环结束

示例:

[root@ansible-salve1 shell]# for i in 1 2 3 4 5 6 ; do echo i=$i;done
i=1
i=2
i=3
i=4
i=5
i=6
[root@ansible-salve1 shell]# for i in {1..10..2};do echo i=$i;done
i=1
i=3
i=5
i=7
i=9
[root@ansible-salve1 shell]# for i in `seq 10`;do echo i=$i;done
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
i=10
[root@ansible-salve1 shell]# sum=0; for i in `seq 10`;do let sum+=i;done;echo sum=$sum
sum=55
[root@ansible-salve1 shell]# 
for循环列表生成方式

直接给出列表

整数列表
{start..end}
$(seq [start [step]] end)
返回列表的命令
$(COMMAND)
使用glob,如:*.sh
# 示例
[root@ansible-salve1 log]# for FILE in `ls /var/log/*.log`;do ll $FILE;done
-rw-------. 1 root root 0 11月 16 08:15 /var/log/boot.log
-rw------- 1 root root 675624 11月 16 07:48 /var/log/dnf.librepo.log
-rw------- 1 root root 81415 11月 16 07:48 /var/log/dnf.log
-rw------- 1 root root 1208 11月 16 07:38 /var/log/dnf.rpm.log
-rw------- 1 root root 39189 11月 16 07:48 /var/log/hawkey.log
-rw------- 1 root root 775 11月 15 04:46 /var/log/vmware-network.1.log
-rw------- 1 root root 775 11月 15 03:54 /var/log/vmware-network.2.log
-rw------- 1 root root 775 11月 14 21:22 /var/log/vmware-network.3.log
-rw------- 1 root root 775 11月 14 06:54 /var/log/vmware-network.4.log
-rw------- 1 root root 775 11月 14 01:21 /var/log/vmware-network.5.log
-rw------- 1 root root 775 11月 13 21:04 /var/log/vmware-network.6.log
-rw------- 1 root root 775 11月 13 04:59 /var/log/vmware-network.7.log
-rw------- 1 root root 775 11月 12 22:00 /var/log/vmware-network.8.log
-rw------- 1 root root 775 10月 28 21:42 /var/log/vmware-network.9.log
-rw------- 1 root root 775 11月 16 07:28 /var/log/vmware-network.log
-rw-r--r--. 1 root root 80892 11月 16 07:28 /var/log/vmware-vmsvc.log
[root@ansible-salve1 log]# 
变量引用,如: $@, $#,$* 位置参数
# 示例
[root@ansible-salve1 shell]# vim info8.sh 
#!/bin/bash
sum=0;
for i in $@;dolet sum+=idoneecho sum=$sum
[root@ansible-salve1 shell]# chmod +x info8.sh 
[root@ansible-salve1 shell]# ./info8.sh 1 2 4 5 6 7 9
sum=34
[root@ansible-salve1 shell]#
示例:打印99乘法表
[root@ansible-salve1 shell]# vim info9.sh 
#!/bin/bash
for i in {1..9};dofor j in `seq $i`;doecho -e "${j}x$i=$((j*i))\t\c "doneecho
done
[root@ansible-salve1 shell]# chmod +x info9.sh
[root@ansible-salve1 shell]# ./info9.sh 
1x1=1   
1x2=2   2x2=4   
1x3=3   2x3=6   3x3=9   
1x4=4   2x4=8   3x4=12  4x4=16  
1x5=5   2x5=10  3x5=15  4x5=20  5x5=25  
1x6=6   2x6=12  3x6=18  4x6=24  5x6=30  6x6=36  
1x7=7   2x7=14  3x7=21  4x7=28  5x7=35  6x7=42  7x7=49  
1x8=8   2x8=16  3x8=24  4x8=32  5x8=40  6x8=48  7x8=56  8x8=64  
1x9=9   2x9=18  3x9=27  4x9=36  5x9=45  6x9=54  7x9=63  8x9=72  9x9=81  
[root@ansible-salve1 shell]# 
生产案例:
将指定目录下的所有文件的后缀都进行备份
# 取出文件的后缀名
[root@ansible-salve1 shell]# echo nianling.sh | sed -En 's/^(.*)\.([^.]+)$/\2/p'
sh
# 取出文件的前缀名
[root@ansible-salve1 shell]# echo nianling.sh | sed -En 's/^(.*)\.([^.]+)$/\2/p'
nainling
​
​
[root@ansible-salve1 shell]# vim info10.sh 
#!/bin/bash
DIR=/root/shell
cd $DIR
for FILE in *;doPRE=`echo $FILE | sed -nr 's/(.*)\.([^.]+)$/\1/p'`cp $FILE $PRE.bak
done
[root@ansible-salve1 shell]# chmod +x info10.sh 

面试题:

要求将目录中YYYY-MM-DD中的所有文件移动到YYYY-MM/DD目录下

 1.创建YYYY-MM-DD,当前日期一年前365天到目前一共365个目录,里面有10个文件,$random.log[root@ansible-salve1 ~]# vim mkdir.sh 
#!/bin/bash
for i in {1..365};doDIR=`date -d "-$i day" +%F`mkdir /data/test/$DIRcd /data/test/$DIRfor n in {1..10};dotouch $RANDOM.logdone
done  
​
# 2.移动到YYYY-MM/DD下[root@ansible-salve1 ~]# mkdir mv.sh
#!/bin/bash
DIR=/data/test
cd $DIR
for DIR in *;doYYYY_MM=`echo $DIR | cut -d"_" -f1,2`DD=`echo $DIR |cut -d"_" -f3`[ -d $YYYY_MM/$DD ] || mkdir -p $YYYY_MM/$DD &> /dev/nullmv $DIR/*  $YYYY_MM/$DD
done

面试题:

扫描一个网段192.168.80.0/24,判断输入的网段中主机的在线状态,将在线的主机IP打印出来

[root@ansible-salve1 ~]# vim ip.sh
#!/bin/bash
IP=192.168.80.
for i in `seq 254`;do{ping -c1 -W1 $IP$i &> /dev/null && echo $IP$i "is up"}&
done
wait     

格式2:

双小括号方法,即((…))格式,也可以用于算术运算,双小括号方法也可以使用bash shell 实现C语言风格的变量操作l=10;((l++))

for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))
do循环体
done

说明:

  • 控制变量初始化:仅在运行到循环代码段时执行一次

  • 控制变量的修正表达式:每轮循环结束后会先进行控制变量修正运算,然后在做条件判断

示例:1到100的和

#!/bin/bash
sum=0
for i in {1..100} ;dolet sum+=i
done
echo sum=$sum
​
sum=0
for ((i=1;i<=100;i++));dolet sum+=i
done
echo sum=$sum  

示例:九九乘法表

#!/bin/bash
for ((i=1;i<10;i++));dofor ((j=1;j<=i;j++));doecho -e "${j}x$i=$((j*i))\t\c"doneecho
done     

示例:打印三角形

# 直角三角形
#!/bin/bash
for((i=1;i<=10;i++));dofor((j=1;j<=2*i-1;j++));doecho -e '*\c'doneecho
done
​
# 等腰三角形
#!/bin/bash
for((i=1;i<=10;i++));dofor((k=1;k<=10-i;k++));doecho -e ' \c'donefor((j=1;j<=2*i-1;j++));doecho -e '*\c'doneecho
done
while循环
[root@ansible-salve1 shell]# help while
while: while 命令; do 命令; done只要测试成功即执行命令。只要在 `while' COMMANDS 中的最终命令返回结果为0,则展开并执行 COMMANDS 命令。退出状态:返回最后一个执行的命令的状态。
[root@ansible-salve1 shell]# 

格式:

while command; do commands;done
​
while condition;do 循环体 done

说明:

在循环控制结构中,条件判断扮演着至关重要的角色。循环开始前,系统会首先对条件进行初次评估。在每一次循环迭代结束后,条件会再次被判断。如果条件为真,则循环体将执行一次。如此往复,直到条件评估为假,循环才终止。因此,循环控制条件通常涉及一个循环控制变量,这个变量的值在循环过程中不断被更新,以确保循环能够在满足特定条件时停止。

进入条件:condition为True

退出条件:condition为False

无限循环
while true;do循环体
done
案例1:猜数游戏
#!/bin/bash
# 脚本生成一个100以内得随机数,提示用户猜数字,根据用户得输入,提示用户猜小了或猜大了,直至用户猜对脚本结束
# RANDOM为系统自带的系统变量,值为0~32767的随机数
# 使用取余算法将随机数变为1~100的随机数
num=$[RANDOM%100+1]
echo $num
​
# 使用read 提示用户猜数字
# 使用if判断用户猜数字的大小关系:
# -eq(等于),-ne(不等于),-gt(大于),-ge(大于等于),-lt(小于),-le(小于等于)
while :
do read -p "数字炸弹在1~100的随机数,请选择数字:" nif [ $n -eq $num ];thenecho "恭喜,爆炸了"exitelif [ $n -gt $num ];thenecho "你猜大了,缩小范围为:0~$n之中"elseecho "你猜小了,缩小范围为$n~100之中"fi
done
案例2:DNS地址查询小程序
#!/bin/bash
# Function 基于DNS字典文件做一个中国电信DNS查询地址
IPPattern='^(\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>\.){3}\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>$'
​
echo -e  "\e[34m --------------------------这是一个指定地区查询对应的DNS地址小程序-------------------------- \e[0m"
read -p "请输入你想查询的省份:" Province
read -p "请输入你想查询的城市: " City
echo -e  "\e[34m --------------------------你查询的地址为$Province$City ,正在为你查询,请稍后---------------------- \e[0m"
count=0
while read line
doprovince=$(echo $line | awk -F " " '{print $2}') #省份city=$(echo $line | awk -F " " '{print $3}') #城市if [[ "${city}" =~ ${IPPattern} ]];thencity=" "dns_address=$(echo $line | awk -F " " '{print $3}') #DNS地址elsedns_address=$(echo $line | awk -F " " '{print $4}') #DNS地址fiif [[ "$province" == $Province* ]];thenif [[ "$city" == $City* ]];thenecho -e "\e[32m $province $city地址为:$dns_address \e[0m"fifi
done < /root/re_study/Shell_Study/dns_list.txt
echo -e  "\e[34m --------------------------这就是以上对$Province$City的DNS地址查询,查询结果仅供参考---------------------- \e[0m"
exit 0
案例3:持续检查服务器负载
#!/bin/bash
#Fuction:持续检查服务器负载,如果负载过高则发送警告邮件
while true
doload=$(uptime | awk '{print $10}'|tr -s "," ' ')if [ $(echo "$load > 1.0" | bc) -eq 1 ];thenecho "Warning:Server load is high:$load" | mail -s "Server load warning" admin@example.comfisleep 300
done
​
# echo "$load > 1.0" | bc 返回一个数字布尔值,0为True,1为False
案例4:持续检查应用日志
#!/bin/bash
#fuction:持续检查错误日志.如有错误日志则发送警告邮件
while true
doif grep -q "Error" /var/log/maillog;thenecho "Warning:Error log found in maillog" | mail -s "Application error" admin@example.comfisleep 600
done
案例5:持续同步文件夹
#!/bin/bash
#Fuction:持续将本地文件夹同步到远程服务器上
while true
dorsync -avz /local/folder/ user@remote-server:/remote/folder/sleep 3600
done
案例6:持续备份数据库
#!/bin/bash
#Fuction:持续备份数据库,每天备份一次
while true:
donow=$(date +"%Y-%m-%d-%H-%M-%S")mysqldump -uroot -p password mydb > "/backup/mydb_$now.sql"sleep 86400
done
案例7:逐行读取文件
#!/bin/bash
#Fuction:逐行读取文件
while read line
doecho $line
done < filename.txt
案例8:计数器循环
#!/bin/bash
#Fuction:计数器循环器
counter=0
while [ $counter -lt 10 ]
doecho $countercounter=$((counter+1))
done
案例9:监听文件变化
#!/bin/bash
while inotifywait -e modify filename
doecho "File Changed"sleep 10
done
循环控制语句continue

continue[N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层

格式:

for (());do循环体1...if command2;thencontinuefiCMDn....
done
示例: 结束最内层循环
#!/bin/bash
for((i=0;i<10;i++));dofor((j=0;j<10;j++));do[ $j -eq 5 ] && continueecho $jdoneecho ----------------------------done
示例:结束外层循环
#!/bin/bash
for((i=0;i<10;i++));dofor((j=0;j<10;j++));do[ $j -eq 5 ] && continue  2echo $j doneecho ----------------------------done
[root@ansible-salve1 shell]# vim info14.sh
[root@ansible-salve1 shell]# bash info14.sh 
0
1
2
3
4
0
1
2
3
4
循环控制语句break

break[N]:提前结束第N层后的全部循环;最内层为第1层,默认为1

示例:结束内层循环
#!/bin/bash
for((i=0;i<10;i++));dofor((j=0;j<10;j++));do[ $j -eq 5 ] && breakecho $j doneecho ----------------------------done
[root@ansible-salve1 shell]# vim info14.sh
[root@ansible-salve1 shell]# bash info14.sh 
0
1
2
3
4
----------------------------
0
1
2
3
4
----------------------------
示例:结束外层循环
#!/bin/bash
for((i=0;i<10;i++));dofor((j=0;j<10;j++));do[ $j -eq 5 ] && break 2echo $j doneecho ----------------------------done
[root@ansible-salve1 shell]# vim info14.sh
[root@ansible-salve1 shell]# bash info14.sh 
0
1
2
3
4
[root@ansible-salve1 shell]# 
​
案例1:餐厅简易点餐系统
#!/bin/bash
sum=0
COLOR='echo -e \033[1;31m'
COLOR2='echo -e \033[1;32m'
END="\033[0m"
​
while true;doecho -e "\033[33;1m\c"cat <<EOF1)鲍鱼2)满汉全席3)龙虾4)燕窝5)帝王蟹6)退出
EOF
echo -e "\033[0m"
​
read -p "请点菜:" MENU
case $MENU in
1|4)$COLOR'菜价:$10'$ENDlet sum+=10;;
3|5)$COLOR'菜价:$20'$ENDlet sum+=20;;
2)$COLOR'菜价:$1000'$ENDlet sum+=1000;;
6)$COLOR2"你点菜的总价格是$sum"$ENDbreak;;
*)echo "没有这道菜,请重新点单";;
esac
$COLOR2"你点的菜总价格是$sum"$END
done`
案例2:持续监控应用状态
#!/bin/bash
#Fuction:基于While循环持续监控应用状态
while true
doif systemctl status sshd | grep -q "active (running)";thenbreakfisleep 10
done
shift技术

在Linux操作系统中,shift命令是一种强大的工具,用于对脚本参数进行向左移动的处理。这种功能在应对参数数量不确定的场景时尤为有用,使得脚本能够依次遍历并处理每一个参数。鉴于其在参数处理中的重要性,shift命令在各种程序的启动脚本中得到了广泛应用。

当执行脚本程序时,如果需要逐个扫描并处理参数,shift命令便显得尤为关键。每当shift命令执行一次,参数序列便会向左移动一个位置,这意味着下一个参数将成为新的第一个参数。相应地, $ #变量记录着脚本后面跟随的参数总数,其值在每次shift调用后会减1。这种机制允许脚本开发人员通过迭代方式逐个处理参数,而无需预先知道参数的确切数量。

需要特别注意的是,那些已经通过shift移出处理范围的参数将不再可用。因此,在使用shift时,必须谨慎考虑参数处理的顺序和逻辑,以确保每个参数都在其有效范围内得到恰当处理。此外, $ n变量可以用来获取脚本后面跟随的第n个参数的具体值,进一步增强了脚本的灵活性和功能性。

[root@nqs22-tps22 ~]# type shift
shift 是 shell 内嵌
[root@nqs22-tps22 ~]# help shift
shift: shift [n]移位位置参数。重命名位置参数 $N+1、$N+2 ... 到 $1、$2 ...  如果没有给定 N,则假设为1.退出状态:返回成功,除非 N 为负或者大于 $#。
参考实例:依次读取输入的参数并打印参数个数:
[root@nqs22-tps22 ~]# vim run.sh
[root@nqs22-tps22 ~]# cat run.sh 
#!/bin/bash
while [ $# != 0 ];do
echo "第一个参数为:$1,参数个数为:$#"
shift
done
[root@nqs22-tps22 ~]# sh run.sh a b c d e f
第一个参数为:a,参数个数为:6
第一个参数为:b,参数个数为:5
第一个参数为:c,参数个数为:4
第一个参数为:d,参数个数为:3
第一个参数为:e,参数个数为:2
第一个参数为:f,参数个数为:1
参考实例:将参数从左到右逐个移动
[root@nqs22-tps22 ~]# vim shift.sh
#!/bin/bash
while [ $# -ne 0 ]
do 
echo "第一个参数为:$1 参数个数为:$#"
shift
done
[root@nqs22-tps22 ~]# sh shift.sh  Lily Lucy Jake Mike
第一个参数为:Lily 参数个数为:4
第一个参数为:Lucy 参数个数为:3
第一个参数为:Jake 参数个数为:2
第一个参数为:Mike 参数个数为:1
[root@nqs22-tps22 ~]# 

http://www.xdnf.cn/news/20314.html

相关文章:

  • Bug排查日记:从崩溃到修复的实战记录
  • Nginx +Tomcat架构的必要性与应用示例
  • Kafka 消息队列:揭秘海量数据流动的技术心脏
  • 具身智能多模态感知与场景理解:融合语言模型的多模态大模型
  • 【关系型数据库SQL】MySql数据库基础学习(一)
  • 高级RAG策略学习(五)——llama_index实现上下文窗口增强检索RAG
  • 在本地使用Node.js和Express框架来连接和操作远程数据库
  • 从“找新家”到“走向全球”,布尔云携手涂鸦智能开启机器人新冒险
  • 突发奇想,还未实践,在Vben5的Antd模式下,将表单从「JS 配置化」改写成「模板可视化」形式(豆包版)
  • langchain 提示模版 PromptTemplate
  • Coze源码分析-资源库-编辑提示词-后端源码
  • 苹果TF签名全称TestFlight签名,需要怎么做才可以上架呢?
  • 如何选择靠谱的软文推广平台?这份行业TOP5清单请查收~
  • AGENTS.md: AI编码代理的开放标准
  • RL【3】:Bellman Optimality Equation
  • 支付DDD建模
  • [光学原理与应用-409]:设计 - 深紫外皮秒脉冲激光器 - 元件 - 窗口镜设计:高透射率、抗损伤与精密调控的终极方案
  • 容器镜像全生命周期管理:从Artifactory制品库搭建到构建节点高效运维
  • Go语言实现以太坊Web3开发
  • 【LeetCode 热题 100】1. 两数之和——(解法二)哈希表
  • 使用tensorRT8部署yolov8/11目标检测模型(1)
  • 无密码登录与设备信任:ABP + WebAuthn/FIDO2
  • IPD模式下跨部门团队管理
  • 力扣152:乘积最大子数组
  • 智慧养老综合实训室建设方案:依托教育革新提升养老人才科技应用能力
  • nestjs 缓存配置及防抖拦截器
  • C# 阿里云 OSS 图片上传步骤及浏览器查看方法
  • 深入解析汇编语言的奥秘
  • 文件不展示Eslint的报错红色
  • 前端三件套+springboot后端连通尝试