马哥教育74期Linux云计算SRE-第04周作业
1. 总结脚本高级命令trap, install, mktemp, expect, 进程优先级命令:nice, renice, 进程管理工具: ps, pstree, prtstat, pgrep, pidof, uptime,mpstat,top,htop, free, pmap, vmstat, iostat, iotop, iftop, nload, nethogs, iptraf-ng, dstat, glances, cockpit, kill, job, 任务相关的命令: at, crontab, 命令,选项,示例。
信号捕捉
trap
命令可以捕捉信号,修改信号原来的功能,实现自定义功能
选项
- 进程收到系统发出的指定信号后,将执行自定义指令,而不会执行原操作
- trap '触发指令' 信号
- 列出所有信号
- trap -l
- 忽略信号的操作
trap ' ' 信号 - 恢复原信号的操作
trap '-' 信号 - 列出自定义信号操作
trap -p - 当脚本退出时,执行finish函数
trap finish exit
安装复制文件
install
功能相当于cp,chmod,chown,chgrp,mkdir等相关工具的集合
选项
- -m 修改权限,默认755
- -o 修改所属主
- -g 修改所属组
- -d 只创建目录
范例:
[root@rocky ~]# useradd shuai
[root@rocky ~]# install -m 700 -o shuai -g shuai -d /data/
[root@rocky ~]# ll -d /data/
drwx------. 2 shuai shuai 6 Apr 16 15:27 /data/
创建临时文件
mktemp
命令用户创建并显示临时文件,可避免冲突
选项
- -d 创建临时目录
- mktemp 文件名XXX(大写X,最少3个X)
- -p /opt/ 指明临时文件所存放目录位置
范例:
[root@rocky ~]# mktemp -p /data/ -d testXXX
/data/test9Lw
交互式转化批处理工具
expect
是由Don Libes基于Tcl(Tool Command Language)语言开发的,主要应用于自动化交互式操作的场景,借助expect处理交互式的命令,可以将交互过程如:ssh登录,ftp登录等写在一个脚本上,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率
选项
- -c 从命令行执行expect脚本,默认expect是交互地执行的
- -d 可以调试信息
范例:
[root@rocky ~]# yum -y install expect
设置和调整进程优先级
nice
命令以更改过的优先序来执行程序,如果未指定程序,则会印出目前的排程优先序,内定的adjustment为10,范围为-20(最高优先序)到19(最低优先序)
进程优先级调整
- 静态优先级:100-139
- 进程默认启动时的nice值为0,优先级为120
- 只有根用户才能降低nice值(提高优先性)
选项
- -n adjustment, -adjustment, --adjustment=adjustment 皆为将该原有优先序的增加 adjustment
范例:
[root@rocky ~]# ps axo pid,cmd,nice |grep ping
17226 ping 127.1 0
17261 grep --color=auto ping 0
[root@rocky ~]# nice -n -10 ping 127.1
[root@rocky ~]# ps axo pid,cmd,nice |grep ping
17266 ping 127.1 -10
17268 grep --color=auto ping 0
rnice
命令可以调整正在执行中的进程的优先级
范例:
[root@rocky ~]# renice -n -20 17270
17270 (process ID) old priority -10, new priority -20
[root@rocky ~]# ps axo pid,cmd,nice |grep ping
17270 ping 127.1 -20
17275 grep --color=auto ping 0
进程信息
ps
命令即process state默认显示当前终端中的进程,类似于windows的任务管理器,Liunx系统各进程的相关信息均保存在/proc/PID目录下的各文件中
选项
- -A 列出所有的进程
- -w 显示加宽可以显示较多的咨询
- -au 显示较详细的资讯
- -aux 显示所有包含其他使用者的进程
范例:
[root@rocky ~]# ps
PID TTY TIME CMD
17232 pts/0 00:00:00 bash
17320 pts/0 00:00:00 ps
[root@rocky ~]# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 174864 6580 ? Ss 13:23 0:02 /usr
root 2 0.0 0.0 0 0 ? S 13:23 0:00 [kth
root 3 0.0 0.0 0 0 ? I< 13:23 0:00 [rcu
root 4 0.0 0.0 0 0 ? I< 13:23 0:00 [rcu
root 6 0.0 0.0 0 0 ? I< 13:23 0:00 [kwo
root 9 0.0 0.0 0 0 ? I< 13:23 0:00 [mm_
root 10 0.0 0.0 0 0 ? S 13:23 0:00 [rcu
root 11 0.0 0.0 0 0 ? S 13:23 0:00 [rcu
root 12 0.0 0.0 0 0 ? S 13:23 0:00 [kso
root 13 0.0 0.0 0 0 ? I 13:23 0:07 [rcu
root 14 0.0 0.0 0 0 ? S 13:23 0:00 [mig
root 15 0.0 0.0 0 0 ? S 13:23 0:00 [wat
root 16 0.0 0.0 0 0 ? S 13:23 0:00 [cpu
root 17 0.0 0.0 0 0 ? S 13:23 0:00 [cpu
root 18 0.0 0.0 0 0 ? S 13:23 0:00 [wat
root 19 0.0 0.0 0 0 ? S 13:23 0:00 [mig
root 20 0.0 0.0 0 0 ? S 13:23 0:00 [kso
root 22 0.0 0.0 0 0 ? I< 13:23 0:00 [kwo
root 25 0.0 0.0 0 0 ? S 13:23 0:00 [kde
root 26 0.0 0.0 0 0 ? I< 13:23 0:00 [net
root 27 0.0 0.0 0 0 ? S 13:23 0:00 [kau
root 31 0.0 0.0 0 0 ? S 13:23 0:00 [khu
root 32 0.0 0.0 0 0 ? S 13:23 0:00 [oom
root 33 0.0 0.0 0 0 ? I< 13:23 0:00 [wri
root 34 0.0 0.0 0 0 ? S 13:23 0:01 [kco
root 35 0.0 0.0 0 0 ? SN 13:23 0:00 [ksm
root 36 0.0 0.0 0 0 ? SN 13:23 0:00 [khu
root 37 0.0 0.0 0 0 ? I< 13:23 0:00 [cry
root 38 0.0 0.0 0 0 ? I< 13:23 0:00 [kin
root 39 0.0 0.0 0 0 ? I< 13:23 0:00 [kbl
root 40 0.0 0.0 0 0 ? I< 13:23 0:00 [blk
root 41 0.0 0.0 0 0 ? I< 13:23 0:00 [tpm
root 42 0.0 0.0 0 0 ? I< 13:23 0:00 [md]
root 43 0.0 0.0 0 0 ? I< 13:23 0:00 [eda
root 44 0.0 0.0 0 0 ? S 13:23 0:00 [wat
root 45 0.0 0.0 0 0 ? I< 13:23 0:00 [kwo
root 78 0.5 0.0 0 0 ? S 13:23 0:47 [ksw
root 180 0.0 0.0 0 0 ? I< 13:23 0:00 [kth
root 181 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 182 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 183 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 184 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 185 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 186 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 187 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 188 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 189 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 190 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 191 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 192 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 193 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 194 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 195 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 196 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 197 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 198 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 199 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 200 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 201 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 202 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 203 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 204 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 205 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 206 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 207 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 208 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 209 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 210 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 211 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 212 0.0 0.0 0 0 ? S 13:23 0:00 [irq
root 213 0.0 0.0 0 0 ? I< 13:23 0:00 [acp
root 214 0.0 0.0 0 0 ? I< 13:23 0:00 [kmp
root 215 0.0 0.0 0 0 ? I< 13:23 0:00 [kal
root 216 0.0 0.0 0 0 ? I< 13:23 0:00 [ipv
root 217 0.0 0.0 0 0 ? I< 13:23 0:00 [kst
root 297 0.0 0.0 0 0 ? I< 13:23 0:00 [kwo
root 511 0.0 0.0 0 0 ? I< 13:23 0:00 [ata
root 512 0.0 0.0 0 0 ? S 13:23 0:00 [scs
root 513 0.0 0.0 0 0 ? I< 13:23 0:00 [scs
root 514 0.0 0.0 0 0 ? S 13:23 0:00 [scs
root 515 0.0 0.0 0 0 ? I< 13:23 0:00 [scs
root 517 0.0 0.0 0 0 ? I< 13:23 0:00 [nvm
root 520 0.0 0.0 0 0 ? I< 13:23 0:00 [nvm
root 522 0.0 0.0 0 0 ? I< 13:23 0:00 [nvm
root 551 0.0 0.0 0 0 ? S 13:23 0:01 [irq
root 553 0.0 0.0 0 0 ? S 13:23 0:00 [car
root 554 0.0 0.0 0 0 ? S 13:23 0:00 [car
root 555 0.0 0.0 0 0 ? S 13:23 0:00 [car
root 556 0.0 0.0 0 0 ? S 13:23 0:00 [car
root 557 0.0 0.0 0 0 ? S 13:23 0:00 [car
root 558 0.0 0.0 0 0 ? S 13:23 0:00 [car
root 559 0.0 0.0 0 0 ? S 13:23 0:00 [car
root 560 0.0 0.0 0 0 ? S 13:23 0:00 [car
root 608 0.0 0.0 0 0 ? I< 13:23 0:00 [kdm
root 617 0.0 0.0 0 0 ? I< 13:23 0:00 [kdm
root 643 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 644 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 645 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 646 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 647 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 648 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 649 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 651 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 652 0.0 0.0 0 0 ? S 13:23 0:02 [xfs
root 745 0.0 0.1 105996 3052 ? Ss 13:23 0:00 /usr
root 788 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 789 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 790 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 791 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 792 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 793 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 794 0.0 0.0 0 0 ? S 13:23 0:00 [xfs
root 798 0.0 0.1 100416 2524 ? Ss 13:23 0:00 /usr
root 830 0.0 0.0 0 0 ? I< 13:23 0:00 [kdm
root 849 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 850 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 851 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 852 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 854 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 857 0.0 0.0 0 0 ? I< 13:23 0:00 [xfs
root 858 0.0 0.0 0 0 ? S 13:23 0:00 [xfs
root 886 0.0 0.0 68232 1536 ? S<sl 13:23 0:00 /sbi
polkitd 916 0.0 0.1 1619912 2936 ? Ssl 13:23 0:00 /usr
dbus 917 0.0 0.1 64668 2724 ? Ssl 13:23 0:00 /usr
root 919 0.0 0.0 125040 172 ? Ssl 13:23 0:01 /usr
root 923 0.0 0.1 171532 3588 ? Ss 13:23 0:00 /usr
root 925 0.0 0.0 72984 0 ? Ss 13:23 0:00 /usr
root 928 0.6 0.1 361340 2496 ? Ssl 13:23 0:56 /usr
chrony 940 0.0 0.0 142148 1324 ? S 13:23 0:00 /usr
root 957 0.0 0.2 182136 5472 ? S 13:23 0:00 /usr
root 965 0.0 1.8 200388 33064 ? S 13:23 0:01 /usr
root 969 0.0 0.0 305116 0 ? Ssl 13:23 0:00 /usr
root 982 0.0 0.2 85132 4328 ? Ss 13:23 0:00 /usr
root 1034 0.0 0.3 391900 5784 ? Ssl 13:23 0:01 /usr
root 1043 0.0 0.1 92428 2264 ? Ss 13:23 0:00 /usr
root 1046 1.2 0.4 494172 7476 ? Ssl 13:23 1:56 /usr
root 1059 0.0 0.1 36992 1848 ? Ss 13:23 0:00 /usr
root 1066 0.0 0.0 13664 0 tty1 Ss+ 13:23 0:00 /sbi
root 1331 0.0 0.1 217712 3024 ? Ssl 13:24 0:02 /usr
root 5863 0.0 0.1 89440 2484 ? Ss 13:29 0:00 /usr
root 5865 0.0 0.0 230172 4 ? S 13:29 0:00 (sd-
root 16716 0.0 0.5 153536 10220 ? Ss 14:18 0:00 sshd
root 16720 0.0 0.3 153536 5560 ? S 14:18 0:02 sshd
root 16721 0.0 0.2 26252 3940 pts/1 Ss 14:18 0:00 -bas
root 16790 0.0 0.0 0 0 ? I 14:32 0:00 [kwo
root 16821 0.1 0.0 0 0 ? I 15:01 0:04 [kwo
root 16842 0.0 0.0 0 0 ? I 15:30 0:01 [kwo
root 16847 0.0 0.0 0 0 ? R 15:33 0:00 [kwo
root 17216 0.0 0.0 0 0 ? I 15:44 0:00 [kwo
root 17224 0.0 0.0 0 0 ? I 15:45 0:00 [kwo
root 17227 0.0 0.5 153536 10472 ? Ss 15:48 0:00 sshd
root 17231 0.0 0.3 153536 5688 ? R 15:48 0:00 sshd
root 17232 0.0 0.2 26252 3956 pts/0 Ss 15:48 0:00 -bas
root 17269 0.0 0.0 0 0 ? I 15:50 0:00 [kwo
root 17270 0.0 0.1 32484 2512 pts/1 S<+ 15:52 0:00 ping
root 17279 0.0 0.2 61692 4112 pts/0 R+ 15:56 0:00 ps -
进程树
pstree
可以用来显示进程的父子关系,以树形结构显示
选项
- -p 显示PID
- -T 不显示线程thread,默认显示线程
- -u 显示用户切换
- -H pid 高亮显示指定进程及其前辈进程
范例:
[root@rocky ~]# pstree -ph
systemd(1)─┬─NetworkManager(1034)─┬─{NetworkManager}(1038)
│ └─{NetworkManager}(1041)
├─VGAuthService(925)
├─agetty(1066)
├─auditd(886)───{auditd}(887)
├─chronyd(940)
├─crond(1059)
├─dbus-daemon(917)───{dbus-daemon}(932)
├─firewalld(969)───{firewalld}(1231)
├─irqbalance(919)───{irqbalance}(941)
├─polkitd(916)─┬─{polkitd}(945)
│ ├─{polkitd}(947)
│ ├─{polkitd}(951)
│ ├─{polkitd}(952)
│ └─{polkitd}(963)
├─rsyslogd(1331)─┬─{rsyslogd}(1343)
│ └─{rsyslogd}(1345)
├─sshd(1043)─┬─sshd(16716)───sshd(16720)───bash(16721)───ping
│ └─sshd(17227)───sshd(17231)───bash(17232)───pstr
├─sssd(923)─┬─sssd_be(957)
│ └─sssd_nss(965)
├─systemd(5863)───(sd-pam)(5865)
├─systemd-journal(745)
├─systemd-logind(982)
├─systemd-udevd(798)
├─tuned(1046)─┬─{tuned}(1315)
│ ├─{tuned}(1323)
│ ├─{tuned}(1324)
│ └─{tuned}(1325)
└─vmtoolsd(928)─┬─{vmtoolsd}(967)
├─{vmtoolsd}(968)
└─{vmtoolsd}(973)
查看进程信息
prtstat
可以显示进程信息,来自于psmisc包
选项
- -r raw格式显示
范例:
[root@rocky ~]# prtstat 928
Process: vmtoolsd State: S (sleeping)
CPU#: 1 TTY: 0:0 Threads: 4
Process, Group and Session IDs
Process ID: 928 Parent ID: 1
Group ID: 928 Session ID: 928
T Group ID: -1
Page Faults
This Process (minor major): 1490 924
Child Processes (minor major): 24794 13
CPU Times
This Process (user system guest blkio): 27.23 39.85 0.00 0.38
Child processes (user system guest): 0.19 0.31 0.00
Memory
Vsize: 454 MB
RSS: 3723 kB RSS Limit: 18446744073709 MB
Code Start: 0x5611fd09e000 Code Stop: 0x5611fd0ad728
Stack Start: 0x7ffed8f2a030
Stack Pointer (ESP): 0 Inst Pointer (EIP): 0
Scheduling
Policy: normal
Nice: 0 RT Priority: 0 (non RT)
[root@rocky ~]# prtstat -r 928
pid: 928 comm: vmtoolsd
state: S ppid: 1
pgrp: 928 session: 928
tty_nr: 0 tpgid: -1
flags: 404100 minflt: 1489
cminflt: 24794 majflt: 924
cmajflt: 13 utime: 2688
stime: 3928 cutime: 19
cstime: 31 priority: 20
nice: 0 num_threads: 4
itrealvalue: 0 starttime: 642
vsize: 454770688 rss: 909
rsslim: 18446744073709551615 startcode: 94635259715584
endcode: 94635259778856 startstack: 140732538200112
kstkesp: 0 kstkeip: 0
wchan: 0 nswap: 0
cnswap: 0 exit_signal: 17
processor: 0 rt_priority: 0
policy: 0 delayaccr_blkio_ticks: 38
guest_time: 0 cguest_time: 0
搜索进程
pgrep
是一个根据名称查找进程ID的命令,返回的是进程ID,若存在当个进程,则分为不同的行返回ID(默认实现)
选项
- -u uid:effective user,生效者
- -U uid:real user,真正发起运行命令者
- -t terminal:与指定终端相关的进程
- -l 显示进程名
- -a 显示完整格式的进程名
- -p pid:显示指定进程的自进程
范例:
[root@rocky ~]# pgrep -au shuai
17328 bash
pidof
命令用于查找指定名称的进程的进程号id号正在运行进程的进程号(pid)的工具,功能类似pgrep和ps
选项
- -x 按脚本名称查找pid
范例:
[root@rocky ~]# pidof bash
17328 17232 16721
负载查询
uptime
/proc/iptime包括两个值,单位s
- 系统启动时长
- 空闲进程的总时长(按总的CPU核数计算)
uptime和w显示以下内容 - 当前时间
- 系统已启动时间
- 当前上线人数
- 系统平均负载(1,5,15分钟的平均负载,一般不会超过1,超过5时建议报警)
系统平均负载:指在特定时间间隔内运行队列中的平均进程数,通常每个CPU内核的当前活动进程数不大于3,那么系统的性能良好。如果每个CPU内核的任务数大于5,那么此主机的性能有严重问题
如:linux主机是1个双核CPU,当Load Average为6的时候说明机器已经被充分使用
范例:
[root@rocky ~]# uptime
16:38:52 up 3:15, 2 users, load average: 0.02, 0.02, 0.00
[root@rocky ~]# w
16:38:54 up 3:15, 2 users, load average: 0.02, 0.02, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.134.1 15:48 6.00s 0.21s 0.00s w
root pts/1 192.168.134.1 14:18 5:58 0.34s 0.00s bash
显示CPU相关统计
mpstat
是一款常用的多核CPU性能分析工具,用来实时查询每个CPU的性能指标,以及所有CPU的平均指标。
范例:
[root@rocky ~]# yum -y install sysstat
[root@rocky ~]# mpstat
Linux 4.18.0-425.3.1.el8.x86_64 (rocky.localdomain) 04/16/2023 _x86_64_ (2 CPU)
04:40:40 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
04:40:40 PM all 0.69 0.01 1.46 0.18 1.72 0.44 0.00 0.00 0.00 95.51
查看进程实时状态
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:虚拟机偷走的时间
选项: -
-d 指定刷新时间间隔,默认为3秒
-
-b 全部显示所有进程
-
-n 刷新多少次后退出
-
-H 线程模式
范例:
[top简介] (https://img2023.cnblogs.com/blog/3093165/202304/3093165-20230416164558355-480089789.png)
htop
命令是增强版的top命令,来自EPEL源,比top功能更强
选项:
- -d 指定延迟时间
- -u UserName:仅显示指定用户的进程
- -s COLUME:以指定字段进行排序
子命令: - s:跟踪选定进程的系统调用
- l:显示选定进程打开的文件列表
- a:将选定的进程绑定至某指定CPU核心
- t:显示进程树
范例:
[root@rocky ~]#yum -y install htop
[htop] (https://img2023.cnblogs.com/blog/3093165/202304/3093165-20230416171918304-1157650862.png)
free
可以显示内存空间使用状态
选项
- -b 以字节为单位
- -m 以MB为单位
- -g 以GB为单位
- -h 易读格式
- -o 不显示-/+buffers/cache行
- -t 显示RAM+SWAP的总和
- -s n 刷新间隔为n秒
- -c n 刷新n次后即退出
范例:
[root@rocky ~]# free
total used free shared buff/cache available
Mem: 1828180 207136 1312388 2012 308656 1471840
Swap: 2125820 85096 2040724
[root@rocky ~]# free -h
total used free shared buff/cache available
Mem: 1.7Gi 202Mi 1.3Gi 1.0Mi 301Mi 1.4Gi
Swap: 2.0Gi 83Mi 1.9Gi
pmap
命令主要用于显示指定进程的内存映像
选项
- -x 显示详细格式的信息
范例:
[root@rocky ~]# pmap -x 17796
17796: ping 127.1
Address Kbytes RSS Dirty Mode Mapping
0000558c220e1000 56 56 0 r-x-- ping
0000558c222ef000 4 4 4 r---- ping
0000558c222f0000 4 4 4 rw--- ping
0000558c222f1000 140 16 16 rw--- [ anon ]
0000558c239e6000 132 24 24 rw--- [ anon ]
00007f0df41ca000 2528 136 0 r---- LC_COLLATE
00007f0df4442000 108 108 0 r-x-- libpthread-2.28.so
00007f0df445d000 2044 0 0 ----- libpthread-2.28.so
00007f0df465c000 4 4 4 r---- libpthread-2.28.so
00007f0df465d000 4 4 4 rw--- libpthread-2.28.so
00007f0df465e000 16 4 4 rw--- [ anon ]
00007f0df4662000 12 12 0 r-x-- libdl-2.28.so
00007f0df4665000 2044 0 0 ----- libdl-2.28.so
00007f0df4864000 4 4 4 r---- libdl-2.28.so
00007f0df4865000 4 4 4 rw--- libdl-2.28.so
00007f0df4866000 88 64 0 r-x-- libz.so.1.2.11
00007f0df487c000 2048 0 0 ----- libz.so.1.2.11
00007f0df4a7c000 4 4 4 r---- libz.so.1.2.11
00007f0df4a7d000 4 0 0 rw--- [ anon ]
00007f0df4a7e000 1524 260 0 r-x-- libunistring.so.2.1.0
00007f0df4bfb000 2044 0 0 ----- libunistring.so.2.1.0
00007f0df4dfa000 16 16 16 r---- libunistring.so.2.1.0
00007f0df4dfe000 4 4 4 rw--- libunistring.so.2.1.0
00007f0df4dff000 1776 1412 0 r-x-- libc-2.28.so
00007f0df4fbb000 2048 0 0 ----- libc-2.28.so
00007f0df51bb000 16 16 16 r---- libc-2.28.so
00007f0df51bf000 8 8 8 rw--- libc-2.28.so
00007f0df51c1000 16 16 16 rw--- [ anon ]
00007f0df51c5000 1540 320 0 r-x-- libm-2.28.so
00007f0df5346000 2044 0 0 ----- libm-2.28.so
00007f0df5545000 4 4 4 r---- libm-2.28.so
00007f0df5546000 4 4 4 rw--- libm-2.28.so
00007f0df5547000 80 64 0 r-x-- libresolv-2.28.so
00007f0df555b000 2048 0 0 ----- libresolv-2.28.so
00007f0df575b000 4 4 4 r---- libresolv-2.28.so
00007f0df575c000 4 4 4 rw--- libresolv-2.28.so
00007f0df575d000 8 0 0 rw--- [ anon ]
00007f0df575f000 2768 832 0 r-x-- libcrypto.so.1.1.1k
00007f0df5a13000 2048 0 0 ----- libcrypto.so.1.1.1k
00007f0df5c13000 176 176 176 r---- libcrypto.so.1.1.1k
00007f0df5c3f000 16 16 16 rw--- libcrypto.so.1.1.1k
00007f0df5c43000 20 8 8 rw--- [ anon ]
00007f0df5c48000 112 64 0 r-x-- libidn2.so.0.3.6
00007f0df5c64000 2048 0 0 ----- libidn2.so.0.3.6
00007f0df5e64000 4 4 4 r---- libidn2.so.0.3.6
00007f0df5e65000 4 0 0 rw--- [ anon ]
00007f0df5e66000 28 28 0 r-x-- libcap.so.2.48
00007f0df5e6d000 2044 0 0 ----- libcap.so.2.48
00007f0df606c000 4 4 4 r---- libcap.so.2.48
00007f0df606d000 4 4 4 rw--- libcap.so.2.48
00007f0df606e000 180 180 0 r-x-- ld-2.28.so
00007f0df6231000 332 128 0 r---- LC_CTYPE
00007f0df6284000 4 4 0 r---- LC_NUMERIC
00007f0df6285000 4 4 0 r---- LC_TIME
00007f0df6286000 4 4 0 r---- LC_MONETARY
00007f0df6287000 4 4 0 r---- SYS_LC_MESSAGES
00007f0df6288000 4 4 0 r---- LC_PAPER
00007f0df6289000 4 4 0 r---- LC_NAME
00007f0df628a000 28 28 0 r--s- gconv-modules.cache
00007f0df6291000 24 24 24 rw--- [ anon ]
00007f0df6297000 4 4 0 r---- LC_ADDRESS
00007f0df6298000 4 4 0 r---- LC_TELEPHONE
00007f0df6299000 4 4 0 r---- LC_MEASUREMENT
00007f0df629a000 4 4 0 r---- LC_IDENTIFICATION
00007f0df629b000 4 4 4 r---- ld-2.28.so
00007f0df629c000 8 8 8 rw--- ld-2.28.so
00007ffc67558000 132 20 20 rw--- [ stack ]
00007ffc675a8000 16 0 0 r---- [ anon ]
00007ffc675ac000 8 4 0 r-x-- [ anon ]
ffffffffff600000 4 0 0 r-x-- [ anon ]
---------------- ------- ------- -------
total kB 32488 4152 416
vmstat
命令是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存,进程,CPU活动进行监控。它是对系统的整体情况进行统计,不足之处是无法对某个进程进行深入分析
显示项说明
procs:
- r:可运行(正运行或等待运行)进程的个数,和核心数有关
- b:处于不可中断睡眠态的进程个数(被阻塞的队列的长度)
- memory:
- swpd:交换内存的使用总量
- free:空闲物理内存总量
- buffer:用于buffer的内存总量
- cache:用于cache的内存总量
swap: - si:从磁盘交换进内存的数据速率(kb/s)
- so:从内存交换至磁盘的数据速率(kb/s)
io - bi:从块设备读入数据到系统的速率(kb/s)
- bo:保存数据至块设备的速率
system: - in:interrupts 中断速率,包括时钟
- cs:context switch 进程切换速率
cpu: - us:Time spent running non-kernel code(运行非内核代码所花费的时间)
- sy:Time spent running kernel code(运行内核代码所花费的时间)
- id:Time spent idle. Linux2.5.41前,包括IO-wait time(闲置的时间。Linux2.5.41前,包括IO等待时间)
- wa:Time spent waiting for IO. 2.5.41前,包括in idle(等待 IO 所花费的时间。2.5.41前,包括空闲)
- st:Time stolen from a virtual machine. 2.6.11前,unknown.(从虚拟机窃取的时间。2.6.11前,未知。)
范例:
[root@rocky ~]# vmstat -s
1828180 K total memory
207824 K used memory
160276 K active memory
141520 K inactive memory
1311660 K free memory
1044 K buffer memory
307652 K swap cache
2125820 K total swap
85092 K used swap
2040728 K free swap
16683 non-nice user cpu ticks
220 nice user cpu ticks
34916 system cpu ticks
2396179 idle cpu ticks
4281 IO-wait cpu ticks
41931 IRQ cpu ticks
10754 softirq cpu ticks
0 stolen cpu ticks
3951307 pages paged in
3053493 pages paged out
654452 pages swapped in
696088 pages swapped out
3471520 interrupts
3599093 CPU context switches
1681622631 boot time
17928 forks
统计CPU和设备IO信息
iostat
可以提供更丰富的IO性能状态数据,此工具由sysstat包提供
选项
- -c 只显示CPU行
- -d 显示设备(磁盘)使用状态
- -k 以千字节为单位显示输出
- -t 在输出中包括时间戳
- -x 在输出中包括扩展的磁盘指标
范例:
[root@rocky ~]# yum -y install sysstat
[root@rocky ~]# iostat -d sda -t -k 1 2
Linux 4.18.0-425.3.1.el8.x86_64 (rocky.localdomain) 04/16/2023 _x86_64_ (2 CPU)
04/16/2023 04:58:01 PM
Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
04/16/2023 04:58:02 PM
Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
监视磁盘I/O
iotop
来自于iotop包命令是一个用来监视磁盘I/0使用状况的top类工具iotop具有与top相似的UI,其中包括PID,用户,I/O,进程等相关信息,可查看每个进程是如何使用
iotop输出
- 第一行:Read和Write速率总计
- 第二行:实际的Read和Write速率
- 第三行:参数如下:
线程ID(按p切换为进程ID)
优先级
用户
磁盘读速率
磁盘写速率
swap交换百分比
IO等待所占的百分比
参数 - -o --only只显示正在产生I/O的进程或线程,除了传参,可以在运行过程中按o生效
- -b --batch非交互模式,一般用来记录日志
- -n NUM,--iter=NUM设置监测的次数,默认无限。在非交互模式下很有用
- -d SEC,--delay=SEC设置每次监测的间隔,默认1秒,接受非整形数据例如1.1
- -p PID,--pid=PID指定监测的进程/线程
- -u USER,--user=USER指定监测某个用户产生的I/O
- -p --processes仅显示进程,默认iotop显示所有线程
- -a --accumulated显示累积的I/O,而不是带宽
- -k --kilobytes使用k8单位,而不是对人友好的单位。在非交互模式下,脚本编程有用
- -t --time加上时间戳,非交互非模式
- -q --quiet 禁止头几行,非交互模式,有三种指定方式
- -q 只在第一次监测时显示列名
- -qq 永远不显示列明
- -qqq 永远不显示I/O汇总
交互按键 - left和right方向键:改变排序
- r:反向排序
- o:切换至选项--only
- p:切换至--processes选项
- a:切换至--accumulated选项
- q:退出
- i:改变线程的优先级
范例:
[root@rocky ~]# yum -y install iotop
[iotop] (https://img2023.cnblogs.com/blog/3093165/202304/3093165-20230416170431614-1827228906.png)
显示网络带宽使用情况
iftop
监控网卡的实时流量(可以指定网段),反向解析IP,显示端口信息,通过EPEL源的iftop包
范例:
[root@rocky ~]#yum -y install iftop
[root@rocky ~]#iftop -ni eth0
interface: eth0
IP address is: 192.168.134.134
MAC address is: 00:0c:29:8a:78:b0
[iftop] (https://img2023.cnblogs.com/blog/3093165/202304/3093165-20230416171752322-576935073.png)
查看网络实时吞吐量
nload
是一个实时监控网络流量和带宽使用情况,以数值和动态图展示进出的流量情况,通过EPEL源安装
界面操作
- 上下方向键,左右方向键,enter键或者tab键都就可以切换查看多个网卡的流量情况
- 按F2显示选项窗口
- 按q或者ctr+c退出 nload
范例:
[root@rocky ~]#yum -y install nload
[root@rocky ~]#nload -u M eth0
[nload eth0] (https://img2023.cnblogs.com/blog/3093165/202304/3093165-20230416172453362-1364228679.png)
查看进程网络带宽的使用情况
nethogs
是一个开源的命令行工具(类似于Linux的top命令),用来按进程或程序实时统计网络带宽使用率
范例:
[root@rocky ~]#yum -y install nethogs
[root@rocky ~]#nethogs
[nethogs] (https://img2023.cnblogs.com/blog/3093165/202304/3093165-20230416172656990-1053632386.png)
网络监视工具
iptraf-ng
来自于iptraf-ng包,可以进网络进行监控,该程序显示有关IP流量的信息,对终端窗口大小有要求
范例:
[root@rocky ~]# yum -y install iptraf-ng
[iptraf-ng] (https://img2023.cnblogs.com/blog/3093165/202304/3093165-20230416174325880-1573041084.png)
系统资源统计
dstat
由pcp-system-tools包提供,但安装dstat包即可,可用于代替vmstat,iostat功能
选项
- -c 显示cpu相关信息
- -C CPU编号,...,total
- -d 显示disk相关信息
- -D total,sda,sdb,...
- -g 显示page相关统计数据
- -m 显示memory相关统计数据
- -n 显示network相关统计数据
- -p 显示process相关统计数据
- -r 显示io请求相关的统计数据
- -s 显示swapped先骨干的统计的数据
- --tcp
- --udp
- --unix
- --raw
- --socket
- --ipc
- --top-cpu:显示最占用PU的进程
- --top-io:显示最占用io的进程
- --top-mem:显示最占用内存的进程
- --top-latency:显示延迟最大的进程
范例:
[root@rocky ~]# yum -y install pcp-system-tools
[dstat] (https://img2023.cnblogs.com/blog/3093165/202304/3093165-20230416174618863-501534980.png)
综合监控工具
glances
是一个跨平台的监视工具,旨在通过curses或基于Web的界面提供大量监视信息,此工具可以通过EPEL源安装
内建命令:
- a Sort processes automatically - l Show/hide logs
- c Sort processes by CPU% - b Bytes or bits for network I/O
- m Sort processes bt MEM% - w Delete warning logs
- p Sort processes bt name - x Delete warning an critical logs
- i Sort processes bt I/O stats - l Global CPU or per-CPU stats
- d Show/hide disk I/O stats - t View network I/O as combination
- f Show/hide file system stats - u View cumulative network I/O
- n Show/hide network stats - q Quit (Esc and Ctrl-c also work)
- s Show/hide sensors stats
- y Show/hide hddtemp stats
选项 - -b:以byte为单位显示网卡数据速率
- -d:关闭磁盘I/O模块
- -f:/path/to/somefile:设定输入文件位置
- -o:{HTML|CSV}:输出格式
- -m:禁用mount模块
- -n:禁用网络模块
- -t:#:延迟时间间隔
- -l:每个CPU的相关数据单独显示
C/S模式下运行glances命令
服务器模式: - glances -c -B IPADDR
IPADDR:指明监听的本机哪个地址,端口默认为61209/tcp
客户端模式: - glances -c IPADDR
IPADDR:要连入的服务器端地址
CentOS8新特性
cockpit
由cockpit包提供,Ubuntu和CentOS7也支持此工具,cockpit时CentOS8取入的新特性,是一个基于Web界面的应用,它提供了对系统的图形化管理
- 监控系统活动(CPU,内存,磁盘IO和网络流量)
- 查看系统日志条目
- 查看磁盘分区的容量
- 查看网络活动(发送和接收)
- 查看用户账户
- 检查系统服务的状态
- 提取已安装应用的信息
- 查看和安装可用更新(如果以root身份登录)并在需要时重新启动系统
- 打开并使用终端窗口
范例:
[root@rocky ~]# yum -y install cockpit
[root@rocky ~]# systemctl enable --now cockpit.socket
Created symlink /etc/systemd/system/sockets.target.wants/cockpit.socket → /usr/lib/systemd/system/cockpit.socket.
[root@rocky ~]# ip a
https://192.168.134.134:9090/system
(https://img2023.cnblogs.com/blog/3093165/202304/3093165-20230416191920958-1243204213.png)
(https://img2023.cnblogs.com/blog/3093165/202304/3093165-20230416191935077-121542632.png)
信号发送
kill
内部命令,可用来向进程发送控制信号,以实现对进程管理,每个信号对应一个数字,信号名称以SIG开头(可省略),不区分大小写
显示当前系统可用信号:
- kill -l
常用信号: - 1)SIGHUP 无须关闭进程而让其重读配置文件
- 2)SIGINT 终止正在运行的进程:相当于Ctrl+c
- 3)SIGQUIT 相当于ctrl+\
- 9)SIGKILL 强制杀死正在运行的进程,可能会导致数据丢失
- 15)SIGTERM 终止正在运行的进程,默认信号
- 18)SIGCONT 继续运行
- 19)SIGSTOP 后台休眠
指定信号的方法: - 信号的数字标识:1,2,9
- 信号完整名称: SIGHUP,sighup
- 信号的简写名称:HUP,hup
范例:利用0信号实现进程的健康性检查
[root@rocky ~]# killall -0 ping
[root@rocky ~]# echo $?
0
[root@rocky ~]# killall -0 ping
ping: no process found
[root@rocky ~]# echo $?
1
jobs
显示Linux中的任务列表及任务状态,包括后台运行的任务。该命令可以显示任务号及其对应的进程号。其中,任务号是以普通用户的角度进行的,而进程号则是从系统管理员的角度来看的。一个任务可以对应于一个或者多个进程号
选项
- -l 显示进程号
- -p 仅任务对应的显示进程号
- -n 显示任务状态的变化
- -r 仅输出运行状态(running)的任务
- -s:仅输出停止状态(stoped)的任务
范例:
[root@rocky ~]# jobs -l
一次性任务
at
指定时间点,执行一次性任务,由包at提供,依赖与atd服务,需要启动才能实现at任务,at队列存放在/var/spool/at目录中,Ubuntu存放在/var/spool/cron/atjobs目录下,执行任务时PATH变量的值和当前定义任务的用户身份一致
选项
- -v 显示版本信息
- -t time 时间格式[[cc]yy]MMDDjjmm[.ss]
- -l 列出指定队列中等待运行的作业;相当于atq
- -d N 删除指定的N号组作业;相当于atrm
- -c N 查看具体作业N号任务
- -f file 指定的文件中读取任务
- -m 当任务被完成之后,将给用户发送邮件,即使没有标准输出
注意: - 作业执行命令的结果中的标准输出和错误以执行任务的用户身份发邮件通知给root
- 默认CentOS8 最小化安装没有安装邮件服务,需要自行安装
/etc/at{allow,deny}控制用户是否能执行at任务 - 白名单:/etc/at.allow默认不存在,只有该文件中的用户才能执行at命令
- 黑名单:/etc/at.deny默认存在,拒绝该文件中用户执行at命令,而没有再at.deny文件中的使用者则可执行
- 如果两个文件都不存在,只有root可以执行at命令
范例:
[root@rocky ~]# at 18:36
warning: commands will be executed using /bin/sh
at> echo abc
at> <EOT>
job 8 at Sun Apr 16 18:36:00 2023
[root@rocky ~]# vim at.txt
[root@rocky ~]# cat at.txt
touch /data/at.log
[root@rocky ~]# at 18:31 <at.txt
[root@rocky ~]# at 18:40 -f at.txt
warning: commands will be executed using /bin/sh
job 10 at Sun Apr 16 18:40:00 2023
[root@rocky ~]# echo "wall at job" |at 18:38
warning: commands will be executed using /bin/sh
job 9 at Sun Apr 16 18:38:00 2023
计划任务
crontab
这个指令所设置的工作将会循环的一直进行下去! 可循环的时间为分、钟、小时、每周、每月、每年
每个用户都有专用的cron任务文件:/var/spool/cron/USERNAME
默认标准输出和错误会被发邮件给对应的用户,如:wang创建的任务就发送至wang的邮箱
root能够修改其它用户的作业
用户的cron中默认PATH-/usr/bin:/bin,如果使用其它路径,在任务文件的第一行加PATH=path或者加入到计划任务执行的脚本中
第六字段指定要运行的命令。该行的整个命令部分,直至换行符或"%"字符,指定的shell执行。除非使用反斜杠(\)进行转义,否则该命令中的"%"字符将变为换行符,并且第一个%之后的所有数据作为标准输入发送到该命令
选项
- -l 列出所有任务
- -e 编辑任务
- -r 移除所有任务
- -i 同-r一同使用,以交互式模式移除指定任务
- -u user 指定用户管理cron任务,仅root可运行
- 计划任务$PASH变量少执行命令加路径
范例:
[root@rocky ~]# crontab -e
[root@rocky ~]# crontab -l
* * * * * echo $PATH >> /data/path.log
[root@rocky ~]# ll /var/spool/cron/ #计划任务放在这里
total 4
-rw-------. 1 root root 39 Apr 16 18:54 root
[root@rocky ~]# cat /var/spool/cron/root #表示root账号创建的任务
* * * * * echo $PATH >> /data/path.log
[root@rocky ~]# cat /var/log/cron #专门的日志可以查看是否执行过
[root@rocky ~]# cat /data/path.log #查看任务的结果
3. 求10个随机数的最大值与最小值。
[root@rocky ~]# vim min_max.sh
#!/bin/bash
declare -i maxnum=0
declare -i minnum=0
for i in `seq 1 10`;do
myrandom=$RANDOM #固定该生成的随机数
[ $i -eq 1 ] && minnum=$myrandom #将第一个随机数赋值给minnum
echo $myrandom #显示每一次循环生成的随机数
if [ $myrandom -ge $maxnum ];then
maxnum=$myrandom
fi
if [ $minnum -ge $myrandom ];then
minnum=$myrandom
fi
done
echo "The maxnum is $maxnum"
echo "The maxnum is $minnum"
[root@rocky ~]# bash min_max.sh
30721
14051
3608
28003
8085
29908
16926
31448
31975
14673
The maxnum is 31975
The maxnum is 3608
4. 使用递归调用,完成阶乘算法实现。
[root@rocky ~]# vim fact.sh
#!/bin/bash
fact() { #fact代表阶乘计算的函数
if [ $1 -eq 0 -o $1 -eq 1 ]; then
echo 1
else
echo $[$1*$(fact $[$1-1])]
fi
}
fact $1
[root@rocky ~]# bash fact.sh 5
120
3. 解析进程和线程的区别?
进程是一个独立的使用资源的使用单位,线程是进程的其中一部分,进程里面至少得有一个线程,具有一定独立功能的程序在一个数据集上的一次动态执行的过程,线程是程序运行单位是操作系统运行程序的一个最小单位,线程有多个它是可以并行执行的同时执行
1.进程是资源分配的最小单位,线程是程序执行的最小单位(资源调度的最小单位)
2.进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段、这种操作非常昂贵。
而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程小很多
3.线程之间的通信更方便,同一进程下的线程共享全局变量,静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。
4.但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另一个进程造成影响,因为进程有自己独立的地址空间
10. 总结Linux,前台和后台作业的区别,并说明如何在前台和后台中进行状态转换。
- 前台进程
在 shell 提示处理打入命令后,创建一个子进程,运行命令, Shell 等待命令退出,然后返回到对用户给出提示符。这条命令与 Shell 异步运行,即在前台运行,用户在它完成之前不能执行别一个命令 。 - 后台进程
在 Shell 提示处打入命令,若后随一个 &, Shell 创建子进程运行此命令,但不等待命令退出,而直接返回到对用户给出提示。这条命令与 Shell 同步运行,即在后台运行。“后台进程必须是非交互式的” 。
后台执行 cmd &
前后台切换
jobs查看作业编号
fg job跟作业编号后台执行的进程放到前台
ctrl+z后台停止状态
bg job后台休眠变成后台执行
15. 总结system启动流程
https://www.junmajinlong.com/linux/systemd/systemd_bootup/
1.UEFi或BIOS初始化,运行POST开机自检
2.选择启动设备
3.引导装载程序,CentOS7是grub2,加载装载程序的配置文件:
/etc/grub.d/
/etc/default/grub
/boot/grub2/grub.cfg
4.加载initramfs驱动模块(可以实现根文件系统的挂载)
5.加载虚拟根中的内核
6.虚拟根的内核初始化,CentOS7使用systemd代替init,第一个进程
7.执行initrd.target所有单元.包括挂载/etc/fstab
8.从initramfs根文件系统切换到磁盘根目录
9.systemd执行默认target配置,配置文件/etc/systemd/system/default.target
10.systemd执行啥意思你太.target初始化系统及basic.target准备操作系统
11.systemd启动multi-user.target下的本机与服务器服务
12.systemd执行multi-user.target下的/etc/rc.d/rc.local
13./systemd执行multi-user.target下的getty.target及登录服务
14.systemd执行graphical需要的服务
通过systemd-analyze工具可以了解启动的详细过程
生成网页:systemd-analyze plot > boot.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话