Linux基础知识、命令完整总结(四)sed、awk、cron、磁盘、进程、软件包

十八、sed流编辑器(取行)

1. sed命令

  • sed 选项 内置命令 文件
    • 选项:
      • -n 取消默认的sed输出
      • -i 直接修改文件内容,而不是输出到终端(-i.bak oldboy.txt oldbot.txt.bak 备份)
      • -e 允许多次编辑
      • -r 实现转义字符 支持扩展正则
    • 内置命令:
      • a 追加文本,指定行后添加一行或文本
      • d 删除
      • i 插入文本,指定行添加一行或多行文本
      • p 打印匹配行的内容
      • s 替换
      • g 全局
# 案例1.打印指定行(-n 取消默认输出,只输出匹配行;指定第2到3行)
sed -n '2,3p' oldgirl.txt

# 案例2.查询字符串(/ /表示过滤,p打印匹配信息)
sed -n '/oldboy/p' oldgirl.txt

# 案例3.删除字符串(/ /表示过滤,d删除匹配字符串)
sed '/oldboy/d' oldgirl.txt

# 案例4.替换字符串(s/想替换啥/用啥替换/g,s表示替换,g表示全局, -i 直接修改文件)
sed  -i 's/oldboy/oldgirl/g' oldgirl.txt


# 案例5.多次编辑(-e 多次修改文件)
sed  -e 's/oldgirl/oldboy/g' -e 's/123/321/g'oldgirl.txt

# 案例6.在第2行后追加信息(a指定行后添加一行或文本,插到了第3行)
sed  '2a hello world!' oldgirl.txt
sed  -i '2a hello world!' oldgirl.txt (直接修改文件)

# 案例7.在第2行插入信息(i指定行插入一行或文本,插到了第2行,\n换行)
sed  '2i hello world!\n one \n two' oldgirl.txt
sed -i '2i hello world!\n one \n two' oldgirl.txt

# 案例8.删除第3行
sed  -i '3d' oldgirl.txt

# 案例9.删除第3到8行
sed  -i '3,8d' oldgirl.txt


# 案例11.删除包含'101'的行到包含'105'的行
sed  -i '/101/,/105/p' oldgirl.txt


# 案例10.获取ifconfig中的第二行的ip地址(-r对"/"进行转义,-n取消默认输出,2s对第二行进行替换,g全局,p打印匹配结果)
ifconfig ens33 | sed -rn '2s#^.*inet (.*)  netm.*$#/1#gp' 
sed  -i '3,8d' oldgirl.txt

2. sed命令执行过程

sed工作流程主要包括读取、执行和显示三个过程

    1. 读取:sed从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式空间pattern space)
    1. 执行:默认情况下,所有的sed命令都在模式空间中顺序的执行,除非指定了行的地址,否则sed命令将会在所有的行上依次执行
    1. 显示:发送修改后的内容输出流。在发送数据后,模式空间将会被清空。在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完

十九、awk操作

在这里插入图片描述

awk 参数 ‘找谁{干啥}’ 文件
awk 参数 ‘条件’ 文件

1. awk命令

  • awk 选项 内置命令 文件

    • -F 指定分隔符(-F “:”)
    • -v 创建或修改awk变量(-vn1=10 -vn2=11)
  • 列:

    • $1:第一列, 2 :第二列, 2:第二列, 2:第二列,n:第n列
    • $0:整行
    • $NF:最后一列
    • $(NF-n):导数第n列
  • 内置变量:

    • RS(默认为\n)(-vRS=\)修改默认换行符
    • OFS 输出分隔符(默认为空格)(-vOFS=:)
    • NR:表示行
    • NF:表示列
  • 条件

    • 、!=、<、>(‘$3>100’、'$4"root")字符串需要加"",否则默认为变量
    • ~ 匹配、/过滤内容/ (‘$0~/root/’、‘ 7   / . p n g 7~/.png 7 /.png/’
  • BEGIN{}

  • END{}

  • 统计

    • {i=i+1}计数出现次数
    • {sum = sum + $10}累积
  • 数组+for循环

    • for(变量 in 数组名)
      • awk 'BEGIN{h[1]=“oldboy”;h[2]=“oldgirl”;h[12306]=“bingbing”;h[103]=“feng”;print h[1],h[2]}
      • awk 'BEGIN{h[1]=“oldboy”;h[2]=“oldgirl”;h[12306]=“bingbing”;h[103]=“feng”;for(n in h) print n,h[n]}
      • awk -F’[/.]+’ ‘{h[$2]++}END{for(n in h) pirnt n,h[n]}’ url.txt
      • awk ‘{KaTeX parse error: Expected '}', got 'EOF' at end of input: 6~/Failed/{h[(NF-5)]++}END{for(n in h) pirnt n,h[n]}’ secure-20161219|sort -rnk2 |head
      • awk ‘{{h[$1]++}END{for(n in h) pirnt n,h[n]}’ access.log|sort -rnk2 |head
  • 内置函数

    • gsub类似sed ‘s#oldboy#oldgirl#g’ count.txt
      • awk ‘{gsub(/bing/,“oldbing”)}1’ count.txt
    • substr类似cut -c
    • split()
# 案例1.以:为分隔符,取第一列(-F 指定分隔符,'{}'内置命令默认格式,print打印操作,$1代表取第一列)
awk -F ":" '{print $1}' oldboy.txt

# 案例2.以:为分隔符,打印第1,3,最后一列
awk -F ":" '{print $1,$3,$NF}' oldboy.txt    -   awk  '{$6~/Failed/{h[$(NF-5)]++}END{for(n in h) pirnt n,h[n]}' secure-20161219|sort -rnk2 |head

# 案例3.取第2,3行
awk 'NR>1&&NR<4' oldboy.txt
awk 'NR==2&&NR==3' oldboy.txt
 
# 案例4.取第2行的最后一列
awk -F ":" 'NR==2{print $NF}' oldboy.txt


# 案例5.过滤出含有root的行(/ /表示过滤)
awk '/root/' oldboy.txt

# 案例6.过滤出以非r开头的行(/ /表示过滤,[^r]非r,^[^r]以非r开头)
awk '^[^r]' oldboy.txt

# 案例7.以:或/为分隔符,打印第1,3,最后一列
awk -F [:/] '{print $1,$3,$NF}' oldboy.txt

# 案例8.以:或连续空格为分隔符,打印第4列,取出ip地址("[:/]+")
ifconfig ens33|awk -F "[:/]+" 'NR==2{print $4}'


# 案例9.匹配第一列内容为root,把符合行的最后一列输出(~为匹配)
awk -F ":" '$1~/root/{print $NF}' test.txt


# 案例10.匹配第三列内容大于70小于95,把符合行输出
awk -F ":" '$3>70&&$3<95/root/{print $0}' score.txt


2. awk命令执行过程

awk命令执行过程

    1. 如果BEGIN 区块存在,awk执行它指定的actions。(在读文件之前进行)
    1. awk从输入文件中读取一行,称为一条输入记录。如果输入文件省略,将从标准输入读取
    1. awk将读入的记录分割成字段,将第1个字段放入变量$1中,第2个字段放入$2,以此类推。$0表示整条记录。字段分隔符使用shell环境变量FS或由参数指定。
    1. 把当前输入记录(数据行)依次与每一个awk_cmd中awk_pattern比较,看是否匹配,如果相匹配,就执行对应的actions。如果不匹配,就跳过对应的actions,直到比较完所有的awk_cmd。
    1. 当一条输入记录比较了所有的awk_cmd后,awk读取输入的下一行,继续重复步骤3和4,这个过程一直持续,直到awk读取到文件尾。
    1. 当awk读完所有的输入行后,如果存在END,就执行相应的actions。

二十、crond定时任务

1. cron介绍

  • 用户定时任务计划
    • 软件名:cron
    • 服务进程名:crond
    • 配置定时任务的命令:crontab

2. crond服务

  • crond服务
    • 任务启动: systemctl start crond.service
    • 停止任务:systemctl stop crond.service
    • 查看服务状态:systemctk status crond.service
  • 开机自启:
    • 开启:systemctl disable crond.service
    • 关闭:systemctl enable crond.service

3. crondtab 设置定时任务

定时任务存放在/var/spool/cron/

1)crondtab命令

  • crondtab
    • l 查看定时任务列表
    • e 编辑定时任务

2)编写定时任务的语法

共六列:
   *        *       *       *       *      command 
(minute)  (hour)  (day)  (month)  (week)     命令
  • 分、时、日、月、周 任务命令/程序

特殊符号|举例|含义
|00 23 * * * cmd|每天23:00
-|00 8-23 * * * cmd|连续区间(8-23点)的整点
,|00 1,3,5 * * * cmd|举例(1点、3点、5点)
/n|
/10 * * * * cmd|每隔(10分钟)

# 案例1.从8:30-18:30,每隔2个小时
30 8-18/2 * * * cmd

# 案例2.每周六日的1:10分
10 1 * * 6,0 cmd

# 案例3.定时打包任务
  00 00 * * * tar zcf /data/html_$(date +、%F).tar.gz /var/www/html &>/dev/null
 (1) 命令行执行
 tar zcf /data/html_$(date +%F).tar.gz /var/www/html
 (2) 使用脚本文件实现(直接编辑定时任务命令时需要注意转义:时间变量%需要\转义)
 mkdir /server/scripts -p # 创建存放脚本的文件夹

 # 将命令写入bak.sh脚本文件中
 cat >bak.sh<EOF
 tar zcf /data/html_$(date +%F).tar.gz /var/www/html
 EOF


 # 测试执行脚本
 /bin/sh /server/scripts/bak.sh

 (3) 编辑定时任务
 crontab -e

 # bak html dir by oldbot at 20240321
  00 00 * * * /bin/sh /server/scripts/bak.sh &>/dev/null

定时任务出错

检查/var/log/cron日志

二十一、Linux磁盘管理

1. Linux磁盘知识体系结构

在这里插入图片描述

  • 第一层:Linux系统硬件层次
  • 第二次:Raid和LVM逻辑层次
  • 第三层:分区层次
  • 第四层:文件系统层
  • 第五层:挂载层次
  • 第六层:文件系统

2. 不同类型磁盘

在这里插入图片描述

  • IDE:ATA硬盘
    • 并行传输
    • 优点:价格低廉、兼容性强、性价比高。
    • 缺点:数据传输速度慢、线缆长度过短、连接设备少。
  • SATA:
    • 串行传输技术
    • 优点:传输速度快、安装方便、容易散热、支持热插拔
  • SCSI:
    • 速度快,稳定性很好,比较适合做磁盘阵列

3、磁盘阵列RAID(硬件)

1)RAID

RAID(Redundant Array of Inexpensive Disks)廉价冗余磁盘阵列,将多个独立的物理磁盘组成一个独立的逻辑盘,数据在多个物理盘上分割交叉存储、并行访问,具有更好的存储性能、可靠性和安全性。

2)RAID分类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、逻辑卷管理LVM(软件)

1)LVM

LVM(Logic Volume Management Manager)逻辑卷管理,灵活的管理磁盘容量,让磁盘可以随意放大和缩小,便于更好的应用磁盘剩余空间。

5、磁盘分区

0)磁盘在Linux中命名

IDE /dev/hda hdb
SCSI /dev/sda sdb

1)磁盘分区类型

    1. 主分区(primary)P
    • 系统中必须要存在的分区,系统盘选择主分区安装
    • 数字编号只能是1-4,sda1、sda2、sda3、sda4。
    • 主分区最多四个,最少一个
    1. 扩展分区(extend)E
    • 相当于一个独立的小磁盘
    • 独立的分区表
    • 不能独立存在,即不能直接存放数据
    • 必须在扩展分区上建立逻辑分区才能存放数据
      • 占主分区的编号(主分区+扩展分区)之后要小于等于4
    • 可以没有,最多一个
    1. 逻辑分区(logic)L
    • 数据编号只能是从5开始
    • 存放在扩展分区之上
    • 存放任意普通数据

注意事项:

  1. 1 <= 主分区数量 <= 4
  2. 2 <= 主分区+扩展分区 <= 4
  3. 若总分区数量 >= 4,必须要分一个扩展分区,扩展分区最多只能有一个
  • 若划分6个分区:
    • 3P+1E(3L) 123 567
    • 2P+1E(4L) 12 5678
    • 1P+1E(5L) 1 56789

2)磁盘的工作原理

在这里插入图片描述

  • 磁盘是按柱面分区的。
  • 磁盘分区表:磁盘分区登记的地点
  • 磁盘分表位置,0磁道,0磁头,1扇区(512字节)
    • 占用1扇区的前446字节(系统引导信息,后缅的4*16=64字节(分区表:主分区+扩展分区),剩下2字节结束表示。

磁盘分区的本质:

修改64节的分区表

3)磁盘分区实战

(1)相关命令
  • fdisk命令 选项 磁盘文件

    • 修改MBR(主引导记录)分区格式
    • 磁盘大小<=2T
  • parted命令

    • 可以修改MBR(主引导记录)分区格式和GPT(统一分区表)分区格式
    • 磁盘大小不限
(2)实践(分区–>文件系统–>挂载)
  1. 添加磁盘

  2. 查看磁盘信息

    • 方法一:ll /dev/sd*

      • 在这里插入图片描述
    • 方法二:lsblk

      • 名称 序号 是否可移动设备 大小 是否只读 磁盘类型 挂载点
      • 在这里插入图片描述
  3. 创建分区:

    • (1)启动分区工具:fdisk /dev/sdc
    • (2)进入会话模式(n新建分区,d删除分区,p查看分区结果,w保存操作,q退出不保存)
      • a. 提示1:(欢迎界面)按n,创建新分区
      • b. 提示2:(选择主分区,或扩展分区)按p,选择主分区
      • c. 提示3:(选择分区号)按1
      • d. 提示4:(选择磁盘开始的扇区)回车选择默认
      • e. 提示5:(选择磁盘结束扇区)输入分区大小"+1G",回车
      • f. 提示6==提示1:(已经完成1G大小的分区记录,但未生效)按w,保持退出
      • g. 提示7:(自动退出分区工具)
    • (3)刷新分区表(将分区信息通知内核):partprobe /dev/sdc
    • (4)查看分区结果:fdisk -l /dev/sdc
  4. 创建文件系统(没有格式化,不可以挂载)

    • mkfs.ext4 /dev/sdc1
  5. 手动挂载点(一个分区一个挂载点)

    • (1)创建挂载点:mkdir /mnt/disk1
    • (2)挂载:mount -t ext4 /dev/sdc1 /mnt/disk1
  6. 查看磁盘信息

    • df -hT

取消挂载:

命令:umount
选项:-lf 强制卸载
umount /mnt/disk1

6、文件系统

1. 基础概念

  • 什么是文件系统
    • 计算机存储和组织数据分方法或机制
  • 为什么需要文件系统
    • 磁盘、物理介质、磁粒子物理元素。硬件需要软件驱动使用,磁盘需要文件系统驱动。
    • 文件系统实现通过磁盘管理规划、存储数据。
  • 文件系统有哪些类型
    • Windows:NTFS、fat32、msdos
    • Linux:ext2、etx3(C5)、ext4(C6)

2. (ext)文件系统原理

3. 创建文件系统实践

(1)相关命令
  • mkfs命令 选项 分区 (创建文件系统)
    • -t 指定文件系统类型
      • -t ext4 等价于 mkfs.ext4
        • mkfs.ext4 /dev/sdb1
      • -b block_size
      • -i inode_size
  • mount命令 选项 分区 挂载目录(挂载文件系统)
    • -t 指定文件类型
      • mount -t ext4 /dev/sdb1 /mnt/disk1
    • -o 挂载的选项
  • umount命令 选项 挂载目录(卸载文件系统)
    • -lf 强制卸载
    • umount -lf /mnt/disk1
  • bklid(查看块设备属性UUID)
  • dumpe2fs(查看ext文件系统细节)
  • fsck(磁盘检查)
(2)自动挂载
  1. /etc/fstab 开机自动挂载
    • 内容:在这里插入图片描述

    • 挂载:/dev/sdc1 /mnt/disk1 ext4 defaults 0 0

  2. /etc/rc.local 开机自动挂载
    • 命令:/sbin/mount -t xfs /dev/sdb2 /opt

二十二、Linux进程管理

1. 基础概念

  • 程序:
    • 概念:为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。(如桌面上的qq应用程序)
  • 进程
    • 概念:进程为静态的程序的一次执行过程,是一个动态的过程。有它自身的产生、存在和消亡的过程。
    • 特点:
      • 资源分配的基本单位
      • 资源包括:cpu、内存、磁盘、网络等
  • 线程
    • 概念:进程进一步细化为线程,是一个程序内部的一条执行路径,如整理家务是一个进程,在收拾家务这个进程中,包含洗衣服、拖地、擦玻璃等多个线程。
    • 特点:
      • 任务调度和执行的基本单位
      • 一个进程中的多个线程共享相同的内存单元

2. 进程的状态

  • R:run 正在运行或在运行队列中等待
  • T:stop 进程收到SIGSTOP,SIGSTP,SIGTIN,SIGTOU信号后停止运行运行。
  • S:sleep 休眠中, 受阻, 在等待某个条件的形成或接受到信号。
  • Z:zombie 进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放。

3. 相关命令

1)静态查看进程

  • ps(查看系统进程)
    • a:显示该终端机下的所有程序,包括其他用户的程序。
    • c:列出程序时,显示程序的指令名称,(不包含路径)
    • e:显示每个程序所使用的环境变量。
    • -f:显示UID,PPIP,C与STIME栏位。
    • f:用ASCII字符显示树状结构,表达程序间的相互关系。
    • -j或j:显示进程归属的进程组id、会话id、父进程id。
    • u:显示进程的归属用户及内存使用情况。
    • x:显示所有程序,不以终端机来区分。
(1)静态查看进程ps aux |less 查看所有进程:(跟踪cpu占用率和内存占用率)
# ps  aux  |less
USER    PID   %CPU   %MEM     VSZ     RSS     TTY     STAT    START   TIME     COMMAND
root     1     1.0    0.3   128236   6952      ?       Ss     19:28   0:01      命令名称


USER:所属用户
PID:进程ID号
%CPU:CPU占用率
%MEM:物理内存占用率
VSZ:占用虚拟内存,单位KB;
RSS:占用实际物理内存,单位KB;
TTY:进程运行的终端。tty1-tty7代表本地终端,pts/0-255代表虚拟终端,?表示内核启动的。
STAT:进程状态
START:进程启动时间
TIME:占用CPU总时间,
COMMAND:命令名
# 案例1. 按cpu占用率排序
ps  aux  --sort  %cpu

# 案例2. 按cpu占用率逆序排序
ps  aux  --sort  -%cpu


(2)ps -ef :(跟踪父进程和完整的启动命令)
# ps -ef  | head -3
UID     PID   PPID    C    STIME    TTY     TIME         CMD
root     1      0     0    19:28     ?      00:00:01     /usr/lib/systemd/systemd
root     2      0     0    19:28     ?      00:00:00     [kthreadd]


UID:用户ID,即进程的拥有者
PID:进程ID
PPID:该进程的父级进程id,如果一个程序的父级进程找不到,该程序的进程被称为僵尸进程
C:cpu的占用率,形式是百分数(%)
STIME:进程开始启动时间
TTY:终端设备,发起该进程的设备识别符号,如果显示‘ ?’表示该进程并不是由终端发起
TIME:进程的执行时间
CMD:该进程的名称或对应的路径
(3)ps axo :(自定义显示字段)
# ps  axo user,pid,ppid,%mem,command  | head -3
USER     PID     PPID      %MEM     COMMAND
root      1       0        0.3      /usr/lib/systemd/systemd 
root      2       0        0.0      [kthreadd]

2)动态查看进程

  • top(查看系统进程)
    • 选项:
      • -d:指定每两次屏幕信息刷新之间的时间间隔
      • -p:通过指定PID来仅仅监控某个进程的状态
      • -c:显示整个命令行而不只是显示命令名
    • 交互:
      • h|?帮助
      • M按内存的使用排序
      • P按CPU使用排序
      • N以PID的大小排序
      • <向前,>向后
# 案例1. 每隔3秒显式所有进程的资源占用情况
top

# 案例2. 每隔1秒显式所有进程的资源占用情况
top -d 1  

# 案例3. 每隔3秒显示pid是28820和pid是38830的两个进程的资源占用情况
top -p 28820 -p 38830   

# 案例4. 每隔2秒显示pid是69358的进程的资源使用情况,并显式该进程启动的命令行参数
top -d 2 -c -p 69358  

#top

top - 16:07:37 up 241 days, 20:11,  1 user,  load average: 0.96, 1.13, 1.25
Tasks: 231 total,   1 running, 230 sleeping,   0 stopped,   0 zombie
Cpu(s): 12.7%us,  8.4%sy,  0.0%ni, 77.1%id,  0.0%wa,  0.0%hi,  1.8%si,  0.0%st
Mem:  12196436k total, 12056552k used,   139884k free,    64564k buffers
Swap:  2097144k total,   151016k used,  1946128k free,  3120236k cached

PID    USER      PR    NI   VIRT    RES     SHR    S   %CPU    %MEM        TIME+   COMMAND
18411  pplive    20     0  11.9g   7.8g    5372    S  220.2    67.1     16761:00   java
1875   pplive    20     0  3958m   127m    4564    S    4.6     1.1     12497:35   java
  4    root      20     0      0      0       0    S    0.3     0.0    184:01.76   ksoftirqd/0
  13   root      20     0      0      0       0    S    0.3     0.0    135:49.83   ksoftirqd/2


第一行: top - 16:07:37 up 241 days,    20:11,     1 user,      load average: 0.96, 1.13, 1.25
        程序名 - 系统时间               运行时间    登录用户数    CPU负载 :   1,5,15分钟
第二行: Tasks: 231 total,    1 running,    230 sleeping,     0 stopped,     0 zombie
        总进程数:总数         运行数1        睡眠进程数207      停止数0        僵死数0
第三行: Cpu(s): 12.7%us,     8.4%sy,   0.0%ni,   77.1%id,   0.0%wa,   0.0%hi,   1.8%si,   0.0%st
        CPU使用占比:us用户   sy系统     ni优先级   id空闲     wa等待     hi硬件    si软件    st虚拟机
第三行: Mem:  12196436k total,     12056552k used,     139884k free,      64564k buffers
        物理内存:total总共2G        userd使用1G          free空闲1G         cache缓存硬盘内容1G
第四行: Swap:  2097144k total,     151016k used,       1946128k free,     3120236k cached
        交换分区内存

3)使用信号控制进程

  • kill -编号 进程号(给进程发送信号)
    • -l 列出所有支持的信号
编号信号名
1SIGHUP 重新加载配置
2SIGINT 键盘中断Ctrl+C
3SIGQUIT 键盘退出Ctrl+\,类似SIGINT
9SIGKILL 强制终止,无条件
15SIGTERM 终止(正常结束),却省略号
18SIGCONT 继续
19SIGSTOP 暂停
20SIGTSTP 键盘暂停Ctrl+Z
# 案例1. 正常结束进程4834
kill -15 4834

# 案例2. 强制终止进程4835
kill -9 4834

二十三、软件包管理

1. 二进制包与源码包

软件包分类概念优点缺点
二进制包(RPM包)编译之后的安装包,无需编译1.代码开源,可修改;2.自由选择所需功能;3.编译安装,效率高;4.卸载方便1.步骤多,时间长;2.编译时间长;3.安装过程易出错
源码包需要经过GCC,C++编译环境编译才能运行1.包的管理系统简单,通过命令对包进行增加删除;2.安装速度快1.看不到源代码;2.功能选择不灵活;3.包之间的依赖性 是个麻烦
  • 源码包优缺点:

    • /usr/local/软件名/
  • 二进制包安装路径:

    • 在这里插入图片描述

2. rpm命令管理

  • rpm 选项 包名
    • -i 安装
    • -v 显示详细信息
    • -h 显示安装进度
    • -q 查询
    • -e 卸载
# 案例1. 安装
rpm  -ivh  wget-1.14-15.el.x86_64.rpm

# 案例2. 查询
rpm  -q  wget

# 案例3. 卸载
rpm  -evh  wget-1.14-15.el7.x86_64

3. yum命令管理(可以自动化处理依赖关系)

  • yum 选项 命令 包名
    • 选项:
      • -y 自动确认
    • 命令:
      • install 安装
      • reinstall 重新安装
      • update 升级安装
      • list 查询软件包
      • remove 卸载程序
  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值