shell和计划任务

shell脚本进阶

循环,控制和菜单

在shell脚本中,有时会重复执行某段代码,通常在进入循环和结束循环时设置条件,以达到重复已知或者未知次数的循环次数

常用的循环命令有:for,while,until

for循环:程序先进行条件判断,判断为真则执行循环体,为假则不执行。常用于遍历列表

for循环的常用格式
#方式1
for 变量名  in 列表;do
 循环体
done
#方式2
for 变量名  in 列表
do
 循环体
done

while:程序先执行循环体,每次循环之后进行田间判断,“true”则继续执行循环,“false”则退出循环。

whiel循环常用格式
while COMMANDS; do COMMANDS; done
while CONDITION; do
 循环体
done

until与while类似,区别在于until判断条件为“false”则继续循环体,“true”则退出循环

until常用格式
until COMMANDS; do COMMANDS; done
until CONDITION; do
 循环体
done
示例
1.for循环
[root@centos7 data]# bash test.sh 
1
2
3
4
5
6
7
8
9
10
[root@centos7 data]# 
[root@centos7 data]# cat test.sh 
#!/bin/bash
for i in {1..10} 
do
echo $i
done
[root@centos7 data]# 
2.while循环
[root@centos7 data]# bash test.sh 
1
2
3
4
5
6
7
8
9
10
[root@centos7 data]# cat test.sh 
#!/bin/bash
i=1
while ((i<=10))
do
echo $i
let i++
done
until循环
[root@centos7 data]# bash test.sh 
1
2
3
4
5
6
7
8
9
10
[root@centos7 data]# cat test.sh 
#!/bin/bash
i=1
until ((i>10))
do
echo $i
let i++
done

有时根据需求,对循环进行控制,continue通过语句执行结果判断循环是否继续,continue #后跟数字表示对第几层循环有效,默认1及当前循环。break通过执行语句结果判断是否中断循环,break #终端第#层循环默认1当前循环。shift [n] 用于将参量列表 list 左移指定次数,缺省为左移一次。 参量列表 list 一旦被移动,最左端的那个参数就从列表中删除。while 循环遍历位置参量列表时,常用 到 shift

示例:
1.
[root@centos7 data]# bash test.sh 
1
2
3
4
6
7
8
9
10
[root@centos7 data]# cat test.sh 
#!/bin/bash
for i in {1..10}
do
  if [ $i -eq 5 ] 
    then
     continue
  fi
echo $i
let i++
done
2.
[root@centos7 data]# bash test.sh 
1
2
3
4
5
6
7
8
9
[root@centos7 data]# cat test.sh 
#!/bin/bash
i=1
while true
do
echo $i
let i++
[ $i -eq 10 ] && break
done
3.
[root@centos7 data]# bash test.sh 1 2 3
1
2
3
[root@centos7 data]# cat test.sh 
#!/bin/bash
while [ -n "$1" ]
do
  echo $1
  shift
done

while 循环的特殊用法,遍历文件或文本的每一行

while read line; do 
	循环体 
done < /PATH/FROM/SOMEFILE 

说明:依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line

[root@centos7 data]# bash test.sh
S
Kernel r on an m

[root@centos7 data]# cat test.sh 
#!/bin/bash
while read line 
do
  echo $line
  shift
done </etc/issue

有时脚本功能较多时会用到菜单select命令,select 循环主要用于创建菜单,按数字顺序排列的菜单项显示在标准错误上,并显示 PS3 提示 符,等待用户输入

用户输入菜单列表中的某个数字,执行相应的命令 用户输入被保存在内置变量 REPLY 中 select 是个无限循环,因此要用 break 命令退出循环,或用 exit 命令终止脚本。也可以按 ctrl+c 退出循环

[root@centos7 data]# bash test.sh
1) 1
2) 2
3) 3
4) 4
5) 5
6) 6
请选择:(1-6):1
1
请选择:(1-6):2
2
请选择:(1-6):q
选择错误,请重新选择
请选择:(1-6):6
6
[root@centos7 data]# cat test.sh 
#!/bin/bash
PS3="请选择:(1-6):"
select menu  in 1 2 3 4 5 6
do
case $REPLY in
1)
echo $menu
;;
2)
echo $menu
;;
3)
echo $menu
;;
4)
echo $menu
;;
5)
echo $menu
;;
6)
echo $menu;break
;;
*)
echo "选择错误,请重新选择"
;;
esac
done

函数和数组

当某段代码使用频率较高时可以考虑函数,实现代码重用和模块化编程

函数由函数名和函数体组成,引用函前需提前定义,在脚本中直接引用。也可将常用函数保存为文件。

#语法一:
func_name (){
 ...函数体...
}
#语法二:
function func_name {
 ...函数体...
} 
#语法三:
function func_name () {
 ...函数体...
} 
1.
[root@centos7 data]# bash test.sh
hello world
[root@centos7 data]# cat test.sh 
#!/bin/bash
hello(){
  echo "hello world"
}
hello
2.
[root@centos7 data]# cat func 
#!/bin/bash
hello(){
  echo "hello world"
}
[root@centos7 data]# . func 
[root@centos7 data]# hello
hello world
注:
export -f function_name 
declare -xf function_name
使用命令可将函数定义为环境函数

数组:存储多个元素的连续的内存空间,相当于多个变量的集合
数组名和索引
索引的编号从0开始,属于数值索引
索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引,bash 4.0版本之后开始支持
bash的数组支持稀疏格式(索引不连续)

普通数组可以不事先声明,直接使用

	declare -a ARRAY_NAME
	#关联数组必须先声明,再使用
	declare -A ARRAY_NAME
[root@centos7 data]# num=({0..10})
[root@centos7 data]# echo ${num[1]}
1
[root@centos7 data]# echo ${num[2]}
2

[root@centos7 data]# declare -A name
[root@centos7 data]# name["ceo"]={"zhang"}
[root@centos7 data]# name["cto"]={"zhao"}
[root@centos7 data]# name["coo"]={"li"}
[root@centos7 data]# echo ${name[*]}
{zhang} {li} {zhao}
[root@centos7 data]# echo ${name[ceo]}
{zhang}
使用命令unset可以删除数组
unset ARRAY[index]  按索引删除
unset ARRAY  整体删除

系统进程和计划任务

进程相关

进程介绍

Process: 运行中的程序的一个副本,是被载入内存的一个指令集合,是资源分配的单位
进程ID(Process ID,PID)号码被用来标记各个进程
UID、GID、和SELinux语境决定对文件系统的存取和访问权限
通常从执行进程的用户来继承
存在生命周期
进程创建:
init:第一个进程,从 CentOS7 以后为systemd
进程:都由其父进程创建,fork(),父子关系,CoW:Copy On Write

进程的状态

进程的基本状态有:创建,就绪,执行,阻塞,终止

进程状态的切换:

运行——>就绪:
1,占用CPU的时间过长,而系统分配给该进程占用CPU的时间是有限的;
2,更高优先级的进程要运行时,该进程就被迫让出CPU,该进程便由执行状态转变为就绪状态
就绪——>运行:运行的进程的时间片用完,调度就转到就绪队列中选择合适的进程分配CPU
运行——>阻塞:正在执行的进程因发生某等待事件而无法执行,则进程由执行状态变为阻塞状态,如
发生了I/O请求
阻塞——>就绪:进程所等待的事件已经发生,就进入就绪队列
以下两种状态是不可能发生的:
阻塞——>运行:即使给阻塞进程分配CPU,也无法执行,操作系统在进行调度时不会从阻塞队列进行
挑选,而是从就绪队列中选取
就绪——>阻塞:就绪态根本就没有执行,谈不上进入阻塞态

进程管理和性能工具

关于进程查看和管理的命令有很多,这里列举常用命令并作举例说明

1.ps

ps 即 process state,可以进程当前状态的快照,默认显示当前终端中的进程,Linux系统各进程的相
关信息均保存在/proc/PID目录下的各文件中

[root@centos7 data]# ps -ef
UID         PID   PPID  C STIME TTY          TIME CMD
root          1      0  0 20:31 ?        00:00:00 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root          2      0  0 20:31 ?        00:00:00 [kthreadd]
root          4      2  0 20:31 ?        00:00:00 [kworker/0:0H]
root          5      2  0 20:31 ?        00:00:00 [kworker/u256:0]

 C 表示 CPU利用率

[root@centos7 data]# ps -aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.2 125364  3812 ?        Ss   20:31   0:00 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root          2  0.0  0.0      0     0 ?        S    20:31   0:00 [kthreadd]
root          4  0.0  0.0      0     0 ?        S<   20:31   0:00 [kworker/0:0H]
root          5  0.0  0.0      0     0 ?        S    20:31   0:00 [kworker/u256:0]


USER          进程所有者的用户名
PID           进程号
START         进程激活时间
%CPU          进程自最近一次刷新以来所占用的CPU时间和总时间的百分比
%MEM          进程使用内存的百分比
VSZ           进程使用的虚拟内存大小,以K为单位
RSS           驻留空间的大小。显示当前常驻内存的程序的K字节数。
TTY           进程相关的终端
STAT          进程状态,包括下面的状态: 
                     D    不可中断     Uninterruptible sleep (usually IO)
                     R    正在运行,或在队列中的进程
                     S    处于休眠状态
                     T    停止或被追踪
                     Z    僵尸进程
                     W    进入内存交换(从内核2.6开始无效)
                     X    死掉的进程
                     <    高优先级
                     N    低优先级
                     L    有些页被锁进内存
                     s    包含子进程
                     +   位于后台的进程组;
                     l    多线程,克隆线程
 
TIME          进程使用的总CPU时间
COMMAND       被执行的命令行
NI            进程的优先级值,较小的数字意味着占用较少的CPU时间
PRI           进程优先级。
PPID          父进程ID
WCHAN         进程等待的内核事件名

按需查看
[root@centos7 data]# ps axo pid,%mem,%cpu
   PID %MEM %CPU
     1  0.2  0.0
     2  0.0  0.0
     4  0.0  0.0
     5  0.0  0.0
     6  0.0  0.0
     7  0.0  0.0
按内存使用排序 --sort 倒叙
[root@centos7 data]# ps axo pid,%mem,%cpu k %mem
   PID %MEM %CPU
     2  0.0  0.0
     4  0.0  0.0
     5  0.0  0.0
     6  0.0  0.0
     7  0.0  0.0

2.pstree

pstree 可以用来显示进程的父子关系,以树形结构显示

-p 显示PID
-T 不显示线程thread,默认显示线程
-u 显示用户切换
-H pid 高亮显示指定进程及其前辈进程
[root@centos7 data]# pstree 1
systemd─┬─NetworkManager───2*[{NetworkManager}]
        ├─VGAuthService
        ├─agetty
        ├─atd
        ├─auditd───{auditd}
        ├─crond
        ├─dbus-daemon
        ├─master─┬─pickup
        │        └─qmgr

3.prtstat

显示进程信息

[root@centos7 data]# prtstat 552
Process: crond         		State: S (sleeping)
  CPU#:  0  		TTY: 0:0	Threads: 1
Process, Group and Session IDs
  Process ID: 552		  Parent ID: 1
    Group ID: 552		 Session ID: 552
  T Group ID: -1

Page Faults
  This Process    (minor major):      603         1
  Child Processes (minor major):     9544         3
CPU Times
  This Process    (user system guest blkio):   0.00   0.00   0.00   0.06
  Child processes (user system guest):         0.01   0.00   0.00
Memory
  Vsize:       129 MB    
  RSS:         1646 kB    		 RSS Limit: 18446744073709 MB
  Code Start:  0x55992c40e000		 Code Stop:  0x55992c41c98c
  Stack Start: 0x7ffe959967d0
  Stack Pointer (ESP): 0x7ffe959962c8	 Inst Pointer (EIP): 0x7f2c7ecf6840
Scheduling
  Policy: normal
  Nice:   0 		 RT Priority: 0 (non RT)

4.top

实时显示进程状态

[root@centos7 data]# top
top - 22:30:53 up  1:59,  1 user,  load average: 0.00, 0.01, 0.05
Tasks: 102 total,   3 running,  99 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1863000 total,  1534672 free,   169520 used,   158808 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.  1539772 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                               
   547 root      20   0  272972   4776   3656 R  0.7  0.3   0:05.72 vmtoolsd                                                                                                              
   288 root      20   0       0      0      0 R  0.3  0.0   0:02.57 xfsaild/sda2                                                                                                          
  1302 root      20   0  161512   6088   4708 S  0.3  0.3   0:00.72 sshd                                                                                                                  
     1 root      20   0  125364   3812   2568 S  0.0  0.2   0:00.69 systemd                                                                                                               
     2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kthreadd                                                                                                              
     4 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kworker/0:0H                                                                                                          
     5 root      20   0       0      0      0 S  0.0  0.0   0:00.13 kworker/u256:0                                                                             
     top 提供动态的实时进程状态 
	帮助:h 或 ? ,按 q 或esc 退出帮助 
	排序: P:以占据的CPU百分比,%CPU 
	M:占据内存百分比,%MEM 
	T:累积占据CPU时长,TIME+ 
首部信息显示: 
	uptime信息:l命令 
	tasks及cpu信息:t命令 
	cpu分别显示:1 (数字) 
	memory信息:m命令 
退出命令:
	q 修改刷新时间间隔:
	s 终止指定进程:
	k 保存文件:W 
top命令栏位信息简介
	us:用户空间 
	sy:内核空间 
	ni:调整nice时间 
	id:空闲 
	wa:等待IO时间 
	hi:硬中断 
	si:软中断(模式切换) 
	st:虚拟机偷走的时间 

系统负载状态

1.uptime,w

查看系统负载状态

[root@centos7 data]# uptime 
 22:40:44 up  2:09,  1 user,  load average: 0.00, 0.01, 0.05
[root@centos7 data]# w
 22:41:13 up  2:09,  1 user,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    10.0.0.1         20:32    1.00s  0.14s  0.00s w
主要查看系统运行时间,在线用户,平均负载等

2.free

查看内存状态

[root@centos7 data]# free
              total        used        free      shared  buff/cache   available
Mem:        1863000      169492     1534656        9684      158852     1539800
Swap:       2097148           0     2097148
内存总量,已用,可用和交换分区状态

4.iostat

[root@centos7 data]# iostat 
Linux 3.10.0-1160.el7.x86_64 (centos7.example.com) 	03/20/2022 	_x86_64_	(1 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.20    0.03    0.17    0.14    0.00   99.45

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               1.61        29.91         9.51     242052      76916
scd0              0.00         0.13         0.00       1028          0
显示cpu状态和磁盘IO信息
tps:该设备每秒的传输次数(Indicate the number of transfers per second that were 
issued to the device.)。"一次传输"意思是"一次I/O请求"。多个逻辑请求可能会被合并为"一次I/O
请求""一次传输"请求的大小是未知的。
kB_read/s:每秒从设备(drive expressed)读取的数据量;
kB_wrtn/s:每秒向设备(drive expressed)写入的数据量;
kB_read:读取的总数据量;
kB_wrtn:写入的总数量数据量;这些单位都为Kilobytes。

kill命令

kill:内部命令,可用来向进程发送控制信号,以实现对进程管理,每个信号对应一个数字,信号名称以 SIG开头(可省略),不区分大小写

常用信号:

  1. 1)SIGHUP 无须关闭进程而让其重读配置文件
  2. 2)SIGINT 中止正在运行的进程;相当于Ctrl+c
  3. 3)SIGQUIT 相当于ctrl+\
  4. 9)SIGKILL 强制杀死正在运行的进程,可能会导致数据丢失,慎用!
  5. 15)SIGTERM 终止正在运行的进程,默认信号
  6. 18)SIGCONT 继续运行
  7. 19)SIGSTOP 后台休眠

作业管理

作业的前台运行,后台运行,终止和并发运行

fg [[%]JOB_NUM]:把指定的后台作业调回前台
bg [[%]JOB_NUM]:让送往后台的作业在后台继续运行
kill [%JOB_NUM]: 终止指定的作业

作业并行:利用后台执行,实现并行功能,即同时运行多个进程,提高效率

方法:
1)
cat all.sh 
f1.sh& 
f2.sh& 
f3.sh&
2)
(f1.sh&);(f2.sh&);(f3.sh&)
3)
f1.sh&f2.sh&f3.sh& 
当执行多个命令并行时可用{}将命令括起来
注:wait   #结束添加,实现非交互推出 

例:
net=10.0.0 
for i in {1..254};do   
{    
if ping -c1 -W1 $net.$i &> /dev/null;then        
echo $net.$i is up    
else        
echo $net.$i is down    
fi   
}& 
done 
wait

计划任务

一次性任务

at工具可创建一次性任务

当前时间延时5分钟输出ok 发送到/var/spool/mail/root中
[root@centos7 data]# at now+5 minutes
at> echo "ok"
at> <EOT>
job 2 at Sun Mar 20 23:07:00 2022
at的时间格式
HH:MM 在今日的 HH:MM 进行,若该时刻已过,则明天此时执行任务
02:00    
HH:MM YYYY-MM-DD   规定在某年某月的某一天的特殊时刻进行该项任务
02:00 2016-09-20   
HH:MM[am|pm] [Month] [Date]
06pm March 17
17:20 tomorrow
HH:MM[am|pm] + number [minutes|hours|days|weeks], 在某个时间点再加几个时间后才进行该
项任务
now + 5 min 
02pm + 3 days
atq可查看所有的一次性任务

周期性任务

cron系统调度进程,crontab命令可用于管理周期性任务

/etc/crontab 配置文件
/etc/cron.d/ 配置文件
/etc/cron.hourly/ 脚本
/etc/cron.daily/ 脚本
/etc/cron.weekly/ 脚本
/etc/cron.monthly/ 脚本

周期任务管理

crontab 
 -u  指定用户
 -e         管理任务
 -l         列出任务
 -r         删除任务
 -i         删除前提示
 时间格式
 计划任务时间表示法:
	(1) 特定值 给定时间点有效取值范围内的值 
	(2) * 给定时间点上有效取值范围内的所有值,表示“每...”,放在星期的位置表示不确定 
	(3) 离散取值 #,#,# 
	(4) 连续取值 #-# 
	(5) 在指定时间范围上,定义步长 /#: #即为步长 
	(6) 特定关健字 
		@yearly 	0 0 1 1 * 
		@annually 	0 0 1 1 * 
		@monthly 	0 0 1 * * 
		@weekly 	0 0 * * 0 
		@daily 	0 0 * * * 
		@hourly	 0 * * * * 
		@reboot 	Run once after reboot 
		
[root@centos7 data]# cat /etc/crontab 
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
  分  时 日 月 周
crontab 创建任务执行脚本时建议生命PATH路径

作业:

1、编写脚本实现登陆远程主机。(使用expect和shell脚本两种形式)。

#!bin/bash
rpm -q sshpass &&  sshpass -p 666666 ssh -o StrictHostKeyChecking=no 10.0.0.27

#!bin/bash
user="root"
ip=10.0.0.27
expect <<EOF 

spawn ssh $user@$ip
        expect { 
                "password" { send "666666\n" } 
        } 
        expect "#" { send "ip a\n" } 
        expect "#" { send "exit\n" } 
        expect eof 
EOF

2、生成10个随机数保存于数组中,并找出其最大值和最小值

#!/bin/bash
for i in {0..9}; do
        num[$i]=$RANDOM
        echo ${num[$i]}
        if [ $i -eq 0 ];then
                max=${num[$i]}
                min=${num[$i]}
        elif [ ${num[$i]} -gt $max ];then
                 max=${num[$i]}
        elif [ ${num[$i]} -lt $min ];then
                min=${num[$i]}
        fi
done
echo "Max:$max"
echo "Min:$min"

3、输入若干个数值存入数组中,采用冒泡算法进行升序或降序排序

#! /bin/bash
n=0
while read num[$n]
do
   n=$[$n+1]
done
len=${#num[*]}
for((i=0;i<len;i++))
do
    for((j=0;j<len-i-1;j++))
    do
        t=$[$j+1]
        #if [[ ${num[$j]}  -gt ${num[$t]} ]] 升序
        if [[ ${num[$j]}  -lt ${num[$t]} ]]  降序
        then
              term=${num[$j]}
               num[$j]=${num[$t]}
               num[$t]=$term
        fi
    done
done
for((k=0;k<len;k++))
do
    echo ${num[$k]}
done

4、总结查看系统负载的几种命令,总结top命令的指标大概什么含义(不要求全部写出来)

free 查看内存状态 已用 可用 缓存等
fdisk 查看各分区利用率
uptime 查看系统运行时间 平均负载等
w 查看当前在线用户,cpu状态
iostat 查看磁盘IO,和cpu状态
top
[root@centos7 data]# top
top - 22:30:53 up  1:59,  1 user,  load average: 0.00, 0.01, 0.05
Tasks: 102 total,   3 running,  99 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1863000 total,  1534672 free,   169520 used,   158808 buff/cache
KiB Swap:  2097148 total,  2097148 free,        0 used.  1539772 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                               
   547 root      20   0  272972   4776   3656 R  0.7  0.3   0:05.72 vmtoolsd 
   运行时间,在线用户,平均负载
   进程信息
   cpu状态
   内存状态
   交换分区状态
   进程ID 所属用户 优先级 cpu 内存使用情况 cpu占用时间 进程

​ 5、编写脚本,使用for和while分别实现192.168.0.0/24网段内,地址是否能够ping通,若ping通则输出"success!",若ping不通则输出"fail!"

#!bin/bash
for i in {1..254}
do
ip=10.0.0.$i
ping -c1 -W1 $ip >/dev/null && echo "$ip sucess"  || echo "$ip fail"  &
done

#!bin/bash
i=1
while [ $i -le 254 ]
do
ip=10.0.0.$i
ping -c1 -W1 $ip >/dev/null && echo "$ip sucess"  || echo "$ip fail"  &
let i++
done
wait

#!bin/bash
i=1
while true 
do
ip=10.0.0.$i
ping -c1 -W1 $ip >/dev/null && echo "$ip sucess"  || echo "$ip fail"  &
let i++
[ $i -eq 255 ] && break
done
wait


​ 6、每周的工作日1:30,将/etc备份至/backup目录中,保存的文件名称格式 为“etcbak-yyyy-mm-dd-HH.tar.xz”,其中日期是前一天的时间

[root@centos7 data]# crontab -l
30 1 * * 1-5 /bin/bash /data/back.sh
[root@centos7 data]# cat back.sh 
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
days=`date +%F-%H-%M -d "yesterday"`
tar -cvpf  etcbak-$days.tar /etc && xz etcbak-$days.tar etcbak-$days.tar.xz
posted @   ——浮生——  阅读(172)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
点击右上角即可分享
微信分享提示