Debian 维护工具之 APT

Debian 维护工具之 APT


本文档是针对 Debian GNU/Linux 的 APT 工具做一般性介绍, 希望 Linux 用户对于 Debian 有个较为深刻的了解.

1. 声明

2. 基本概念

dpkg 功能十分的强大, 是它保证了系统的稳定性. 但是随着 GNU/Linux 的日益普及, Debian 操作系统的广泛应用, dpkg 在操作上日益显示出它的不足之处. APT (高级软件包工具 Advanced Package Tool)很好的解决了这一难题, 它功过抽取软件包中的相关信息, 给出相关操作的优化方案, 确定解决请求所需软件包, 从资源库下载, 根据需求在本地系统安装和删除软件包.

dpkg 采取的方式较为保守, 当发现进一步操作可能会将问题引入系统时(比如使系统中出现了不能满足依赖关系的软件), 将拒绝执行这一操作(默认方式), APT则会根据出现的问题, 智能的给出解决方案, 并继续进行操作. 比如,安装操作出现依赖关系时, dpkg 会拒绝操作, APT 则不同, 将会自动安装这些依赖包以完成安装请求.

APT 提供另一个简单的命令行方式, 与 dpkg 不同, 其本身不会处理 .deb 文件, 而是智能从资源库下载, 然后调用 dpkg 仅此处理. APT 是 dpkg 的一个智能前端.

3. 基本配置

apt 通过名称和版本来在确定一个软件包, 这些信息通常是通过资源库中提供的 Packages.gz (如果是源代码则是 Source.gz)来抽取来的(通过 apt-get update 获取). 通常如果出现重复的软件包, 则第一个有效. 这些资源库在 etc/apt/sources.list/ 中定义.

3.1 自动配置

在基本系统中提供了一个用于自动配置资源列表的工具: apt-setup. 由 base-config(现在仅在 sarge 中提供) 软件包中, 可以通过

#base-config
调用, 或者直接运行
#apt-setup

进行配置.

3.2 手动配置

资源库在 /etc/apt/sources.list 中用就象如下行定义:

 deb     ftp://some-server/debian sarge main contrib
deb-src ftp://some-server/debian sarge main contrib

与网站有如下对应关系:

         ftp://some-server/debian/dists/sarge/main/binary-i386/...
ftp://some-server/debian/dists/sarge/contrib/binary-i386/...
------------------------ ----- | |
/___ / | |
add: / / | |
------------------------ ----- | |
deb ftp://some-server/debian sarge main contrib

当然上边的网站是假设的, 不可用的. 应当选择您连接速度最快的镜像地址替换. Debian 官方镜像列表可以 从 http://www.debian.org/mirror/list 处获取, 也可从 /var/lib/apt-spy/mirrors.txt(apt-spy 提供)得到. 至于私有资源则需要通过别的途径获取.

/etc/apt/sources.list 中, 每行为一条记录, 定义一个资源库. 其具体语法在 sources.list(5) 联机手册中有详细介绍.每条记录至少包括三个字段, 共同组成资源定位. 这些字段是:

软件包类型

deb 指二进制软件包. 要访问软件包源代码, 则必需用 deb-src 代替.

资源URI

统一资源标识符(URI)用于指定资源库, 可以使用下边任意一种方式访问:

cdrom, file, copy, http, ftp, ssh

发行版(distribution)

在标准的镜像中, 这一字段使用规范名称(如 stable )或代号(如 sarge )来关联 Debian 的发行版.

构成

用于关联一个发行版的组成部分, 对应官方镜像,相当于软件库(如 每个条目的其余部分用于关联一个发行版提供的组成部分.对于官方镜像,这相当于软件库(如 main, contrib), 对于非官方资源库, 组成部分的关联方式可以由管理员自己定义. APT会为每个构成创建单独的 URI. 因此, 正常的发行版至少需要一个组成部分.

在修改 sources.list 后或安装软件前, 需要对APT进行更新, 就是运行 apt-get uodpate 获取各种 Packages 文件, 它的位置是通过 /etc/apt/sources.list 中的记录来指定的.每个提到构成都有一个对应的 Packages 文件.

3.3 优化资源

apt-spy 方式

Debian 在互联网上有庞大的镜像群, 有超过 100 个提供了全部 Debian 归档库的官方镜像. 另外, 还有很多大学和机构提供非官方镜像, 因此使用附近的还是不错的. 我们将哪些镜像加入我们的 sources.list 文件呢? 当然是速度最快的! Debian 为我们提供了一个用户测试镜像速度的工具 apt-spy (由 apt-spy 提供). 这样有利于有效的利用带宽, 节省下载时间.

可以从 http://www.debian.org/mirror/list (由于某种原因, 您可能无法访问)处获取获取完整的镜像列表. 也可以从 tt /var/lib/apt-spy/mirrors.txt / ( apt-spy 提供)找到一个副本.

apt-spy 通过对列表进行测试, 根据带宽和回应速度, 找出其中最快的一个, 并将结果自动保存到 /ect/apt/sources.list 中.

#apt-get install apt-spy

#mv sources.list sources.list.bak //backup

#man apt-spy //获取详细的使用方法

#apt-spy update //更新您的镜像列表文件 /var/lib/apt-spy/mirrors.txt

可将测试限制在一个国家或区域内, 提供限制测试服务器个数的选项, 等等. 另外, 区域也可以在 /etc/apt-spy.conf 中定义. 可以通过下边的命令找出亚洲区速度最快的镜像,并生成针对 testing 的记录:

# apt-spy -d testing -a Asia

上边的测试大概每个服务器需要用一分钟的时间, 这个也可以使用 -t 选项控制. 有关这一选项的详细信息请阅读 apt-spy(8) 联机手册.

netselect-apt 方式

netselect-apt 会创建一个更完整的 sources.list 文件, 但它使用更落后的方法来选择镜像站点:

#apt-get install netselect-apt

#mv sources.list sources.list.bak //backup

#man netselect-apt //获取详细的使用方法

# netselect-apt -s testing

//下载 http://www.debian.org/mirror/list-full文件, 并根据其内容测试网络, 生成 sources.list

也可将下载 http://www.debian.org/mirror/list-full 手动下载到本地, 并同过参数 -i 指定. 同样可以通过 -o 参数指定输出文件而不是默认的 sources.list

4. APT 的配置

APT 的很多方面都是可以定制的.事实上,在 /etc/apt/apt.conf 文件中, 您可以修改大多数命令行选项的默认值. 配置参数使用 名称 - 值 对,根据用途被分为几组. 组名在参数前边用 "::" 分割.tt apt.conf(5) 联机手册有相关语法介绍. 其它项目在对应命令的联机手册中有所描述(如 tt apt.get(1) tt apt-cache(1) ). 比如:

APT::Default-Release "testing";

//在使用混合系统时, 设定默认下载的版本

APT::Get::Assume-Yes "true";

//如果在安装/卸载过程中出现询问, 应答为 y

如果在使用aptitudeapt-getdpkg 时出现如下错误

E: Dynamic MMap ran out of room

可以在apt.conf中加入:

APT::Cache-Limit "12500000";

以重新设定缓存区大小.

访问资源库需要代理, 则可以加入类似下边的内容:

Acquire::http::proxy "http://user:pass@xxx.xxx.xxx.xxx:port"; 
Acquire::ftp::proxy "ftp://user:pass@xxx.xxx.xxx.xxx:port";

APT还提供了三个钩子程序, 用于在 dpkg 阶段调用.它们分别是 Pre-Invoke, Post-Invoke, Pre-Install-Pkgs.

DPkg::Pre-Invoke {"mount -o remount,rw /usr";};
DPkg::Post-Invoke {"mount -o remount,ro /usr";};
DPkg::Pre-Install-Pkgs {"dpkg-preconfigure --apt --priority=low --frontend=dialog";};

/usr/share/doc/apt/examples/apt.conf, /usr/share/doc/apt/examples/configure-index.gz 中给出详细的例子, 可以用于参照.

5. 安装

当发出安装请求时,apt 会根据其优化算法, 求解出最佳安装方案, 来完成用户的请求. 比如:

debian:~# apt-get install xchat
Reading Package Lists... Done
Building Dependency Tree... Done
The following extra packages will be installed:
defoma fontconfig libatk1.0-0 libfontconfig1 libgtk2.0-0 libgtk2.0-bin
libgtk2.0-common libpango1.0-0 libpango1.0-common libperl5.8 libtiff4
libx11-6 libxcursor1 libxext6 libxft2 libxi6 libxrandr2 libxrender1 tcl8.4
ttf-bitstream-vera xchat-common xfree86-common xlibs-data
Suggested packages:
defoma-doc psfontmgr x-ttcidfont-conf dfontmgr ttf-kochi-gothic
ttf-kochi-mincho ttf-thryomanes ttf-baekmuk ttf-arphic-gbsn00lp
ttf-arphic-bsmi00lp ttf-arphic-gkai00mp ttf-arphic-bkai00mp tclreadline
libnet-google-perl x-window-system-core x-window-system
Recommended packages:
libft-perl libatk1.0-data hicolor-icon-theme
The following NEW packages will be installed:
defoma fontconfig libatk1.0-0 libfontconfig1 libgtk2.0-0 libgtk2.0-bin
libgtk2.0-common libpango1.0-0 libpango1.0-common libperl5.8 libtiff4
libx11-6 libxcursor1 libxext6 libxft2 libxi6 libxrandr2 libxrender1 tcl8.4
ttf-bitstream-vera xchat xchat-common xfree86-common xlibs-data
0 upgraded, 24 newly installed, 0 to remove and 1 not upgraded.
Need to get 12.5MB of archives.
After unpacking 39.1MB of additional disk space will be used.
Do you want to continue? [Y/n]

APT 下载软件时是根据 /var/lib/apt/lists 下的 _Packages 文件, 来获取软件的详细定位的, 而这些 _Packages 文件是通过命令:

#apt-get update

命令从 sources.list 中声明的顺序从资源库中获取的. 这一命令将对 Packages 索引文件进行更新. 因此, 在安装软件前, 或在修改 sources.list 后, 应该进行 apt-get update 操作.

每天运行, 或经常运行这一命令, 是个良好的习惯. APT 同时会清除/var/lib/apt/lists 目录下没有在 /etc/apt/sources.list 中声明的资源文件. 如果你使用 --no-list-cleanup(APT::Get::List-Cleanup),APT 将会保留这些文件,如果您只是在 sources.list 中临时禁用一条资源, 这样还是比较方便的; 当再次启用这条资源时, 就不需要重复下载 APT 的资源文件了.

在安装的时候您可以通过使用 --print-uris 选项将这些信息输出到屏幕. 比如:

#apt-get install --print-uris  nano-tiny
Reading Package Lists... Done
Building Dependency Tree... Done
The following NEW packages will be installed:
nano-tiny
0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Need to get 87.8kB of archives.
After unpacking 123kB of additional disk space will be used.
'http://ftp.us.debian.org/debian/pool/main/n/nano/nano-tiny_1.2.4-5_i386.deb'
nano-tiny_1.2.4-5_i386.deb 87786 07794bf630d1a9dffdf85917a9e39968

注意 后边的 07794bf630d1a9dffdf85917a9e39968 这是 nano-tiny_1.2.4-5_i386.deb 的 MD5 编码, 将用跟从 Packages 中获取的对应 MD5 编码相比对. 只有 MD5 编码相匹配时, 才会安装. 当出现不一致时, APT 会报告 MD5 不匹配,并拒绝安装或升级软件包.

您也可以仅仅模拟一下, 而不是真正的安装:

#apt-get install nano-tiny -s(--simulate)

如果您仅需要获取 .deb, 而不是装, 则可以

#apt-get install nano-tiny -d(--download-only)

假如你不小心损坏了已安装的软件包而想修复它, 或者仅仅想安装软件包中某些文件的最新版本, 这是可以做到的, 你可以用 --reinstall 选项:

# apt-get --reinstall install nano

如果您使用的是混合源, 也可指定发行版安装:

# apt-get install nano/testing

解决依赖问题

当出现依赖问题时, APT 会努力做出最好的的选择. 作为解决依赖问题的一部分, APT 为了尽可能的完成用户的请求, 会首先卸载已经安装的冲突的软件包. 无论何时, 在进行用户请求的附加操作时, apt-get 在提示了对所选择软件包将要做的的变更后, 都会请求用户的确认. 这是为了防止不小心卸载了冲突的软件包, 或引入更严重的依赖问题. 如果不需要额外的操作, APT 将不会给出提示.

通过设置 APT::Get::Show-Upgradeedtrue ,可以让APT每次都提示确认. 同样, 设置 APT::Get::Assum-Yestrue, 或在APT的命令行指定 -y 选项, APT 将绕过确认, 继续操作. 请避免使用这一选项;确认对于生产应用系统来说是个好事情. 有时, 一个软件包会依赖于其它一组软件包中的任意一个. 比如:

debian:~# apt-cache depends mailx
mailx
Depends: libc6
Depends: liblockfile1
|Depends: exim4
Depends: <mail-transport-agent>
courier-mta
esmtp-run
exim
masqmail
nullmailer
postfix
sendmail-bin
ssmtp
xmail
exim4-daemon-heavy
exim4-daemon-light
Depends: base-files
Conflicts: <suidmanager>

mailx 依赖于能够提供 邮件传输代理的任一个软件包, 在默认情况下会安装 exim4, 除非您明确指定:

#apt-get install mailx postfix

6. 查询

到目前为止, 一切感觉都还不错, 只要您知道了软件包名称, 使用APT安装简直就是小菜一碟. 当我们需要安装一个软件, 而又没有确切的知道其名称时, 就需要求助于 apt 提供的另一个命令 apt-cache (详细的使用方法, 请查阅 apt-cache(8) 联机手册). 它可以用于查询您的软件包数据库, 包括软件包描述, 就象这样:

debian:~# apt-cache search mysql-server
mysql-server - mysql database server (current version)
mysql-server-4.1 - mysql database server binaries
mysql-server-5.0 - mysql database server binaries
phpbb2-conf-mysql - Automatic configurator for phpbb2 on
scoop - Web-based collaborative media application
webmin-mysql - mysql-server control module for webmin

我们找到了几个相关的软件包, 以及有关的简单描述. 想进一步获得某个软件包的详细信息, 你可以运行:

#apt-cache show mysql-server
Package: mysql-server
Priority: optional
Section: misc
Installed-Size: 8344
Maintainer: Christian Hammers <ch@debian.org>
Architecture: i386
Source: mysql-dfsg
Version: 4.0.24-10sarge1
Provides: virtual-mysql-server
Depends: mysql-common (>= 4.0.24-10sarge1), mysql-client (>= 4.0.24-10sarge1),
ebconf (>= 1.2.9), libdbi-perl, perl (>= 5.6), libc6 (>= 2.3.2.ds1-21), libgcc
(>= 1:3.4.1-3), libmysqlclient12, libstdc++5 (>= 1:3.3.4-1), libwrap0, zlib1g
= 1:1.2.1), adduser (>= 3.40), psmisc, passwd, mailx
Conflicts: mysql-server-4.1
Filename: pool/updates/main/m/mysql-dfsg/mysql-server_4.0.24-10sarge1_i386.deb
Size: 3645680
MD5sum: b1877cc602daf4b3aeffd350ced6f6a7
Description: mysql database server binaries
MySQL is a fast, stable and true multi-user, multi-threaded SQL database
server. SQL (Structured Query Language) is the most popular database query
language in the world. The main goals of MySQL are speed, robustness and
ease of use.
.
This package includes the server binaries for the 4.0 branch.

如果仅想了解某软件包的与哪些软件包关联, 可运行:

debian:~# apt-cache depends mysql-server
mysql-server
Depends: mysql-common
Depends: mysql-client
Depends: debconf
Depends: libdbi-perl
Depends: perl
Depends: libc6
Depends: libgcc1
Depends: libmysqlclient12
Depends: libstdc++5
Depends: libwrap0
Depends: zlib1g
Depends: adduser
Depends: psmisc
Depends: passwd
Depends: mailx
mailutils
Conflicts: mysql-server-4.1

而命令

debian: # apt-cache rdepends mysql-server

则会查询哪些包依赖于mysql-server. 如果要将这两种查询信息合并到一起, 则可以使用:

debian: # apt-cache showpkg mysql-server

apt-cache search 的参数可以使用正则表达式, 如果指定了多个参数, 则输出的软件包必需同时包含这它们这些内容. 也可以使用 --name-only 选项( APT::Cache::NameOlny true ),只搜索软件包名. 当指定 --full 选项(APT::Cache::ShowFull true )时, 将会显示软件包的所有信息.

7. 高级查询

如果你想安装某个软件包, 但用 apt-cache 查不出它的名称,不过你知道这个程序的文件名, 或这个软件包中某些文件的文件名, 那么你可以用 apt-file 来查找软件包名称. 这个工具由同名软件包提供. apt-file 事实上是一个 APT 软件库中提供的 Contents 文件的接口. 每个发行版都提供这样的文件, 包括了某个发行版所要安装的所有文件的列表. 在使用 apt-file 前, 需要首先获取用户要查询的 Contents 文件. 运行 apt-file update 将会这个文件下载到 /var/cache/apt 目录. 这样就可以使用 apt-file 查询这个文件了. apt-file 的主要用途是确定某个文件是由哪个软件包提供的.

$ apt-file search filename

用这个命令, 你可以列出软件包的内容:

$ apt-file list packagename

apt-get 一样, 这个数据库也需要实时更新, 完成更新可以运行:

# apt-file update

8. 卸载和清除

如果你不再使用某些软件包, 你可以用 APT 将其从系统中删除. 要删除软件包只需输入: apt-get remove package. 如下所示:

debian:~# apt-get remove vim
Reading Package Lists... Done
Building Dependency Tree... Done
The following packages will be REMOVED:
vim vim-common
0 upgraded, 0 newly installed, 2 to remove and 1 not upgraded.
Need to get 0B of archives.
After unpacking 15.1MB disk space will be freed.
Do you want to continue? [Y/n]

可以注意到, 在请求删除 vim 时, vim-common 也会同时卸载, 因为 APT 会关注那些与被删除的软件包有依赖关系的软件包. 使用 APT 删除一个软件包将会连带删除那些与该软件包有依赖关系的软件包. 但是它们的配置文件, 如果有的话, 会完好无损地保留在系统里. 如果想彻底删除这些包及其配置文件,运行:

debian:~# apt-get remove vim --purge
Reading Package Lists... Done
Building Dependency Tree... Done
The following packages will be REMOVED:
vim* vim-common*
0 upgraded, 0 newly installed, 2 to remove and 1 not upgraded.
Need to get 0B of archives.
After unpacking 15.1MB disk space will be freed.
Do you want to continue? [Y/n]

注意软件包后的星号, 这表示将要被清除, 而不是简单的删除.

您也可以在安装的同时进行软件卸载, 比如:

debian:~# apt-get install nano-tiny nano-
Reading Package Lists... Done
Building Dependency Tree... Done
The following packages will be REMOVED:
nano
The following NEW packages will be installed:
nano-tiny
0 upgraded, 1 newly installed, 1 to remove and 1 not upgraded.
Need to get 0B/87.8kB of archives.
After unpacking 913kB disk space will be freed.
Do you want to continue? [Y/n]

注意 nano 后边的 "-", 它提示在安装 nano-tiny 的同时将nano 卸载掉.

当然也可以用 dpkg 进行软件包删除, 但是它并不能自动解决依赖问题.

9. 系统升级

9.1 软件升级

Debian 的一个强大之处就是它的对软件包的无缝升级. 无论是请求APT将一个持续相当长时间的的 woody 服务器升级到 sarge, 还是对当前 stable 发行版升级一些软件包,APT 都不会有问题. 升级软件包就是指一个软件包版本号比当前安装的版本号要高. 从 Debian 的一个发行版升级到另一个, 软件包的版本号都作了刻意的增加,而 stable 内部的升级则是因为安全问题, 和重大补丁修正, 而不可能是功能调整. 如果新的上游版本修正了某个安全问题, 则安全修正仍会使用 stable 版中的版本号, 以尽量减少变动. Debian/stable 要确保系统的稳定性.

一个 stable 版本所包含的软件包列表可能从不会改变, 但是一个新的发行版通常会引入等多的软件包. 因此, stable 内部的依赖关系从不会发生变化, 但是新的发行版中可能会包含更名, 或拆分的软件包, 因此需要修改软件包之间的依赖关系.

版本内升级, 只需一条命令即可完成更新:

#apt-get upgrade

运行该命令时加上 -u 选项很有用. 这个选项让 APT 显示完整的可更新软件包列表. APT 会下载每个软件包的最新更新版本, 然后以合理的次序安装它们. 注意在运行该命令前应先运行 apt-get update 更新数据库. 定时顺序执行 update/upgrade, 可以保持系统运行平稳和安全. 也可以使用 cron 自动升级系统.

9.2 升级到新版本

不同的版本之间, 提供的软件包的数目, 以及软件包间的依赖关系会有很大差异, 如果更改新的版本, 比如将系统从 stable 升级到 testing, update/upgrade 不会安装没有在系统中出现的软件包; 只会对现存软件包进行升级. 并且如果现有软件新版本依赖关系发生而来变化, 那么将无法对其升级:

debian:~# apt-get upgrade
Reading Package Lists...
Building Dependency Tree...
The following packages have been kept back:
adduser apache apache-common apache2-utils apt apt-utils aptitude bc
...

The following packages will be upgraded:
base-files base-passwd bash binutils bitchx bootcd bootcd-i386 bsdmainutils
...

142 upgraded, 0 newly installed, 0 to remove and 83 not upgraded.
Need to get 51.8MB of archives.
After unpacking 12.5MB of additional disk space will be used.
Do you want to continue? [Y/n]

我们看到有些包被阻止更新(kept back), 现在我们就用使用APT的智能升级机制: apt-get dist-upgrade

debian:~# apt-get dist-upgrade
Reading Package Lists...
Building Dependency Tree...
The following packages will be REMOVED:
libgssapi1-heimdal libroken16-kerberos4kth libsp1 mysql-common-4.1
postfix-tls
The following NEW packages will be installed:
apache2-common apache2-mpm-prefork cpp-4.0 dmidecode gcc-4.0 gcc-4.0-base
...
The following packages will be upgraded:
adduser apache apache-common apache2-utils apt apt-utils aptitude base-files
...
225 upgraded, 42 newly installed, 5 to remove and 0 not upgraded.
Need to get 132MB of archives.
After unpacking 70.6MB of additional disk space will be used.
Do you want to continue? [Y/n]

apt-get dist-upgrade 时, APT 会安装新软件包,甚至会删除废弃的软件包. 实际的新软件包的安装, 或删除旧软件包, 仍是由 dpkg 完成的.

几分钟(也可能是几个小时, 这和你 的带宽和升级的软件包的多少有关)后, APT 就完成了系统从 stable 到 testing 的升级.因为仍是有 dpkg 来响应实际的安装, 您精心调整的配置文件并不会被修改(除非您选择安装新的版本). 当新版的软件包需要修改调整文件时, Debian 的维护者将会提供不同的软件包, 这样您就不必花费整个下午的时间来调整您的软件恢复正常了.

10. 解决问题

  • 如何将本地光盘加入安装源列表:
    这可以求助于 apt-cdrom add
  • 如何降级一个系统(比如将 sid 降级为 testing)

    /etc/apt/preferences文件中加入:

            Package: *
    Pin: release a=testing
    Pin-Priority: 1001
    修改 /etc/apt/sources.list, 将资源库由 sid 改为 testing 分支, 然后运行:
    #apt-get update

    #apt-get -u dist-upgrade

    注: 降级处理存在一定的风险, 谨慎使用
  • 如果在安装过程中出现中断, 然后你发现该软件包既不能重装又不能删除, 试试下面两个命令:
    # apt-get -f install

    # dpkg --configure -a

  • 如何清除下载到本地的软件库

    #apt-get clean
    //将删除 /var/cache/apt/archives/ 目录和 /var/cache/apt/archives/partial/ 目录下的所有文件,除了被锁定的文件.

    apt-get autoclean
    //仅删除那些不需要再次下载的文件.
  • 如何查看一个软件的编译依赖库

    #apt-cache showsrc packagename|grep Build-Depends
    注: sources.list 中应该有 deb-src
  • 下载软件的源代码

    #apt-get source packagename
    注: sources.list 中应该有 deb-src 源
  • 安装软件包源码的同时, 安装其编译环境

    #apt-get build-dep packagename
    注: sources.list 中应该有 deb-src 源
  • 检查软件包的状态

    #apt-cache policy packagename

11. 参考文献

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值