对话unix——unix高手的秘密

<div id="ibm-content-main">
<!-- Related_Searches_Area_And_Overlays_Begin --><!-- MAIN_COLUMN_CONTAINER_BEGIN -->
<div class="ibm-container">
<!-- MAIN_COLUMN_CONTENT_BEGIN -->
<p>如果您想知道我为何佩戴黑色太阳镜、假胡须和棒球帽(模仿一个专业冰壶球队 The Floating Stones 的徽标),那是因为我正在逃亡之中。我正在躲避黑色的遥控直升机、面色苍白的系统管理员和许多 “妖魔鬼怪” 的追踪,我这样做的目的只有一个,就是向您披露 UNIX® 高手的重大秘密。请戴上您的铝箔帽阅读本文吧! </p>
<p><a name="environment_variables"></a></p>
<p>大多数 UNIX 用户在 .bashrc(针对 Bash shell)和 .zshrc(针对 Z shell)等 shell 启动文件中塞满大量用户设置,以便一次又一次地重建钟爱的 shell 环境。启动文件能够创建别名、设置 shell 选项、创建函数、以及设置环境变量。关键的环境变量包括 HOME(指向您的主目录)、PATH(列举从中搜索应用程序的目录)和 MANPATH(列举从中搜索手册页的目录)。要查看您的 shell 中设置了哪些环境变量,键入 <code><span style="font-size: small;">printenv</span></code> 命令。查阅 shell 手册页,获取可用环境变量的完整列表。 </p>
<p>与 shell 一样,可以通过环境变量定制其他许多 UNIX 应用程序。例如,Java™ 子系统要求定义 JAVA_HOME 来指向 Java 运行时的根。同样,Amazon Web Services (AWS) 实用程序套件强制使用 AWS_CREDENTIAL_FILE 来指向一个包含有效私匙凭证的文件。单独的应用程序也提供环境变量,关键是如何发现这些变量。幸运的是,这种工作不需要非法入侵;相反,只需查询手边的实用工具手册页,查找标题为 “Environment Variables” 的章节即可。 </p>
<p>例如,分页实用程序 <code><span style="font-size: small;">less</span></code> 定义了几个有用的环境变量: </p>
<ul>
<li>环境变量 LESS 存储一些命令行选项,以在您每次调用该分页程序时减少键入量。例如,如果您需要阅读大量日志文件,可将以下语句添加到一个 shell 启动文件中:
<table style="width: 50%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycodeliquid">export LESS='--RAW-CONTROL-CHARACTERS --squeeze-lines --ignore-case'
</pre>
</td>
</tr></tbody></table>
<br>`
<p>上述选项将分别解译控制字符(通常是语法着色),将多个空行压缩为一行,并忽略字符串匹配中的大小写。如果您使用代码,可尝试以下选项: </p>
<table style="width: 50%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycodeliquid">export LESS='--LINE-NUMBERS --quit-if-one-screen --quit-on-intr'
</pre>
</td>
</tr></tbody></table>
</li>
<li>名为 LESSKEY 的环境设置指向一个密匙绑定文件。可以使用密匙绑定来定制 <code><span style="font-size: small;">less</span></code> 的行为,比如,匹配另一个页面或编辑器的行为。 </li>
<li>与 shell 一样,<code><span style="font-size: small;">less</span></code> 能保留多个调用之间的历史。设置 LESSHISTFILE 和 LESSHISTSIZE 分别指向一个持久命令文件和设置要记录的命令的最大条数。 </li>
</ul>
<p>GNU Compiler Collection (GCC) 是另一个典型的环境变量应用示例。GCC 定义各种环境变量来定制其操作。LIBRARY_PATH,顾名思义,是一个目录列表,用于搜索要链接到的库;COMPILER_PATH 的工作方式与 shell 的 PATH 非常相似,但是由 GCC 在内部使用,用于查找编译过程中使用的子程序。 </p>
<p>如果您针对单个平台写代码并构建二进制文件,您可能永远也不会用到这些环境变量,但是,如果您跨平台交叉编译相同的代码,那么这些变量对于访问每个平台的不同的头部和库至关重要。您可以将这些变量设置为不同的值集合,一个集合针对一种机器,而另一个集合针对另一种风格的系统。 </p>
<p>事实上,您可以从 GCC 获得一个暗示:可以为每个应用程序维护多个环境变量集合,根据手边的工作从一个集合切换到另一个集合。一种方法是在每个项目目录中保存一个环境初始化文件并根据需要 <code><span style="font-size: small;">source</span></code> 它。例如,许多 Ruby 开发人员使用这种方法来在不同的 Ruby 版本间切换,根据需要更改环境变量 PATH、GEM_HOME 和 GEM_PATH,从一个版本跳到另一个版本。 </p>
<div class="ibm-alternate-rule">
<hr>
</div>
<p><a name="landscape"></a></p>
<p>与环境变量非常相似的是,许多 Linux® 和 UNIX 应用程序都提供一个<strong>点</strong> 文件 — 文件名以圆点开始的小文件 — 来进行定制。与环境变量不同的是:环境变量采集少量标记和相对较少的信息量,而点文件可能更广泛、更复杂,拥有自己独特的语法规则、甚至自己的编程语言。点文件是保存选项和设置的理想位置,因为(根据 UNIX 传统)以一个圆点开始的文件名不会出现在标准的目录清单中。(使用 <code><span style="font-size: small;">ls -a</span></code> 来查看这些所谓的<strong>隐藏文件</strong>。)点文件是纯文本文件,只是文件名比较特别而已。 </p>
<p>点文件通常位于您的主目录内,但有些实用程序也在当前工作目录中查找点文件。如果一个应用程序支持多个点文件,则该程序通常应用于优先规则,来表明一个文件比另一个文件优先。通常,“本地” 点文件 — 位于当前工作目录 — 优先级最高,然后是主目录中的点文件,最后是一个系统范围配置文件。这些文件可以全部存在,也可以存在一个,或者都不存在,这取决于应用程序将这些文件视为互斥的还是递增的。在第一种情况下,优先链中第一个点文件的优先权是不容置疑的。在后一种情况下,配置可以级联或融解到最终结果中。 </p>
<p><code><span style="font-size: small;">less</span></code> 的密匙绑定文件是一个简单点文件示例,位于 $HOME/.lesskey 中。文件中的每一行都是一对(一个按键和一条命令),如下所示: </p>
<table style="width: 65%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycode">/r forw-line
/n forw-line
e forw-line
j forw-line
^E forw-line
^N forw-line
k back-line
y back-line
^Y back-line
</pre>
</td>
</tr></tbody></table>
<br><p><code><span style="font-size: small;">fetchmail</span></code> 是比较复杂的点文件示例。这个实用程序在本地从多个远程源提取电子邮件并传送消息。这个实用程序的操作只通过 $HOME/.fetchmailrc 控制。(参见手册页了解它的众多选项。)<code><span style="font-size: small;">cron</span></code>、<code><span style="font-size: small;">git</span></code>、<code><span style="font-size: small;">vi</span></code>,以及其他许多命令都能识别点文件。同样,请阅读这个应用程序的手册页,了解可以在点文件中配置的内容。有些点文件内容丰富,足以占用一个单独的手册页,比如 <code><span style="font-size: small;">crontab</span></code>。 </p>
<div class="ibm-alternate-rule">
<hr>
</div>
<p><a name="secrets"></a></p>
<p>Secure Shell (SSH) 是一个功能强大的子系统,用于安全地登录到远程系统、复制文件并穿越防火墙。由于 SSH 是一个子系统,它提供大量选项来定制和简化其操作。事实上,SSH 提供名为 $HOME/.ssh 的整个 “点目录” 来包含其所有数据。(您的 .ssh 目录必须是模式 600,以阻止他人访问。非 600 模式将干扰正常的操作。)特别是,文件 $HOME/.ssh/config 可以定义大量快捷方式,包括机器名称的别名、每主机访问控制等。 </p>
<p>下面是位于 $HOME/.ssh/config 中的一个典型代码块,用于定制一个特定主机的 SSH:</p>
<table style="width: 65%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycode">Host worker
HostName worker.example.com
IdentityFile ~/.ssh/id_rsa_worker
User joeuser
</pre>
</td>
</tr></tbody></table>
<br><p>~/.ssh/config 中的每个块配置一个或多个主机。不同的块使用一个空行分隔。这个块使用 4 个选项:<code><span style="font-size: small;">Host</span></code>、<code><span style="font-size: small;">HostName</span></code>、<code><span style="font-size: small;">IdentityFile</span></code> 和 <code><span style="font-size: small;">User</span></code>。<code><span style="font-size: small;">Host</span></code> 为 <code><span style="font-size: small;">HostName</span></code> 指定的机器创建一个昵称。昵称允许您键入 <code><span style="font-size: small;">ssh worker</span></code>,而不是 <code><span style="font-size: small;">ssh worker.example.com</span></code>。另外,<code><span style="font-size: small;">IdentityFile</span></code> 和 <code><span style="font-size: small;">User</span></code> 选项指定如何登录到 <code><span style="font-size: small;">worker</span></code>。前者指向此主机使用的一个私匙,后者提供登录 ID。这样,这个代码块就等同于以下命令: </p>
<table style="width: 65%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycode">ssh joeuser@worker.example.com -i ~/.ssh/id_rsa_worker
</pre>
</td>
</tr></tbody></table>
<br><p><code><span style="font-size: small;">ControlMaster</span></code> 是一个鲜为人知的强大选项。如果设置,同一个主机的多个 SSH 会话将共享单个连接。一旦第一个连接建立,后续连接就不再需要凭证,从而消除了每次连接同一机器都需要键入密码的麻烦。<code><span style="font-size: small;">ControlMaster</span></code> 非常方便,您可能愿意为每台机器启用它。启用方法非常简单,只需使用主机通配符 <code><span style="font-size: small;">*</span></code>: </p>
<table style="width: 65%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycode">Host *
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p
</pre>
</td>
</tr></tbody></table>
<br><p>如您所料,标记了 <code><span style="font-size: small;">Host *</span></code> 的块将应用到每个主机,甚至是那些在配置文件中没有明确指定的主机。<code><span style="font-size: small;">ControlMaster auto</span></code> 尝试使用一个现有连接,并在没有发现共享连接时创建一个新连接。<code><span style="font-size: small;">ControlPath</span></code> 指向一个文件,以便持久化一个控制套接字以供共享。<code><span style="font-size: small;">%r</span></code> 用远程登录用户名替换,<code><span style="font-size: small;">%h</span></code> 用目标主机名替换,<code><span style="font-size: small;">%p</span></code> 代替连接使用的端口。(您还可以使用 <code><span style="font-size: small;">%l</span></code>,它使用本地主机名替换。)上述规范使用类似于下面的文件名创建控制套接字: </p>
<table style="width: 65%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycode">master-joeuser@worker.example.com:22
</pre>
</td>
</tr></tbody></table>
<br><p>当到远程主机的所有连接都被切断时,每个控制套接字都就会被移除。如果您想随时了解连接到了哪些主机,只需键入 <code><span style="font-size: small;">ls ~/.ssh</span></code> 并查看控制套接字的主机名部分(<code><span style="font-size: small;">%h</span></code>)。 </p>
<p>SSH 配置文件非常大,它也有自己的手册页。键入 <code><span style="font-size: small;">man ssh_config</span></code> 查看所有可能的选项。这里有一个巧妙的 SSH 技巧:可以通过 SSH 从本地系统进入远程系统。要用到的命令行如下所示: </p>
<table style="width: 65%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycode">$ ssh example.com -L 5000:localhost:3306
</pre>
</td>
</tr></tbody></table>
<br><p>这条命令的意思是:通过 example.com 进行连接,并在本地机器上的端口 5000 和名为 “localhost” 的机器上的端口 3306(MySQL 服务器端口)之间建立一条通道。由于 <code><span style="font-size: small;">localhost</span></code> 在 example.com 上解释(因为通道已建立),因此 <code><span style="font-size: small;">localhost</span></code> 就是 example.com。由于出站通道 — 以前称为<strong>本地转发(local forward)</strong>— 已建立,本地客户端能够连接到端口 5000,并与 example.com 上运行的 MySQL 服务器通信。 </p>
<p>通道创建的常规形式如下:</p>
<table style="width: 65%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycode">$ ssh <strong>proxyhost</strong>
<strong>localport</strong>:<strong>targethost</strong>:<strong>targetport</strong>
</pre>
</td>
</tr></tbody></table>
<br><p>其中,<code><strong><span style="font-size: small;">proxyhost</span></strong></code> 是可以通过 SSH 访问的机器,并且拥有一个到 <code><strong><span style="font-size: small;">targethost</span></strong></code> 的网络连接(不通过 SSH)。<code><strong><span style="font-size: small;">localport</span></strong></code> 是您的本地系统上的一个非特权端口(1024 以上的任一未用端口),<code><strong><span style="font-size: small;">targetport</span></strong></code> 是您要连接到的服务的端口。 </p>
<p>前面的命令从您的机器发送<strong>出去</strong>,到达外部世界。 也可以使用 SSH 发送<strong>进来</strong>,或者从外部世界连接到您的本地系统。入站通道的常规形式如下: </p>
<table style="width: 65%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycode">$ ssh <strong>user</strong>@<strong>proxyhost</strong> -R <strong>proxyport</strong>:<strong>targethost</strong><strong>targetport</strong>
</pre>
</td>
</tr></tbody></table>
<br><p>建立一条入站通道 — 以前称为<strong>远程转发</strong> — 时,<code><strong><span style="font-size: small;">proxyhost</span></strong></code> 和 <code><strong><span style="font-size: small;">targethost</span></strong></code> 的角色将被反转:目标是您的本地机器,代理是远程机器。<code><strong><span style="font-size: small;">user</span></strong></code> 是您在代理上的登录名。以下命令提供了一个具体示例: </p>
<table style="width: 65%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycode">$ ssh joe@example.com -R 8080:localhost:80
</pre>
</td>
</tr></tbody></table>
<br><p>这条命令的意思是:用户 Joe 连接到 example.com,并将远程端口连接到本地端口 80。这条命令向 example.com 上的用户提供一个通道,以连接到 Joe 的机器上。远程用户能够连接到 8080,以便连接 Joe 机器上的 Web 服务器。 </p>
<p>除了分别用于本地和远程转发的 <code><span style="font-size: small;">-L</span></code> 和 <code><span style="font-size: small;">-R</span></code> 之外,SSH 还提供 <code><span style="font-size: small;">-D</span></code> 参数来在远程机器上创建一个 HTTP 代理。请参见 SSH 手册页了解正确语法。 </p>
<div class="ibm-alternate-rule">
<hr>
</div>
<p><a name="history"></a></p>
<p>如果您经常在 shell 提示符中花费大量时间,保存 shell 历史记录可以节约时间和输入。但是如果历史记录不能被修改,就会导致一些麻烦:记录重复的命令,且多个 shell 实例可能会干扰各自的历史记录。这两个问题很容易解决,只需在您的 .bashrc 中添加两行: </p>
<table style="width: 65%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycode">export HISTCONTROL=ignoreboth
shopt -s histappend
</pre>
</td>
</tr></tbody></table>
<br><p>第一行将移除您的 shell 历史记录中连续的重复命令。如果您想移除所有零散的副本,可将 <code><span style="font-size: small;">ignoreboth</span></code> 更改为 <code><span style="font-size: small;">erasedups</span></code>。第二行在 shell 退出时将 shell 的历史记录附加到您的记录文件。默认情况下,Bash 记录文件命名为 <strong>~/~/.bash_history</strong> (不错,这是一个点文件)。可以通过设置 HISTFILE(不错,这是一个环境变量)来更改它的位置。如果您想将一个 shell 的最近 10,000 命令保存在一个包含 100,000 条目的记录文件中,将 <code><span style="font-size: small;">export HISTSIZE=10000 HISTFILESIZE=100000</span></code> 添加到您的 shell 启动文件中。要查看一个 shell 的历史记录,在任意提示处键入 <code><span style="font-size: small;">history</span></code> 即可。 </p>
<p>如果不能调用,那么保存的命令历史记录就用处不大。而这正是 shell <code><span style="font-size: small;">!</span></code>(或 bang)操作符的作用所在: </p>
<ul>
<li>
<code><span style="font-size: small;">!!</span></code> ("bang bang") 完整地重复最后一条命令。 </li>
<li>
<code><span style="font-size: small;">!:0</span></code> 是前一条命令的名称。</li>
<li>
<code><span style="font-size: small;">!^</span></code> 是前一条命令的第一个参数。<code><span style="font-size: small;">!:2</span></code>、<code><span style="font-size: small;">!:3</span></code> ... <code><span style="font-size: small;">!$</span></code> 等命令是前一条命令的第二、第三......以及最后一个参数。 </li>
<li>
<code><span style="font-size: small;">!*</span></code> 是最后一条命令的所有参数,命令名除外。 </li>
<li>
<code><span style="font-size: small;">!<strong>n</strong></span></code> 重复历史中编号为 <code><strong><span style="font-size: small;">n</span></strong></code> 的命令。 </li>
<li>
<code><span style="font-size: small;">!<strong>handle</strong></span></code> 重复以 <code><strong><span style="font-size: small;">handle</span></strong></code> 中的字符开始的最后一条命令。例如,<code><span style="font-size: small;">!ca</span></code> 将重复以字符 <code><span style="font-size: small;">ca</span></code> 开始的最后一条命令,如 <code><span style="font-size: small;">cat README</span></code>。 </li>
<li>
<code><span style="font-size: small;">!?<strong>handle</strong></span></code> 重复<strong>包含</strong> <code><strong><span style="font-size: small;">handle</span></strong></code> 中的字符组成的字符串的最后一条命令。例如,<code><span style="font-size: small;">!?READ</span></code> 还会匹配 <code><span style="font-size: small;">cat README</span></code>。 </li>
<li>
<code><span style="font-size: small;">^<strong>original</strong>^<strong>substitution</strong></span></code> 使用 <code><strong><span style="font-size: small;">substitution</span></strong></code> 替换 <code><strong><span style="font-size: small;">original</span></strong></code> 的<strong>第一个</strong> 实例。例如,如果前一条命令是 <code><span style="font-size: small;">cat README</span></code>,,命令 <code><span style="font-size: small;">^README^license.txt</span></code> 将生成一条新命令 <code><span style="font-size: small;">cat license.txt</span></code>。 </li>
<li>
<code><span style="font-size: small;">!:gs/<strong>original</strong>/<strong>substitution</strong></span></code> 将使用 <code><strong><span style="font-size: small;">substitution</span></strong></code> 替换 <code><strong><span style="font-size: small;">original</span></strong></code> 的<strong>所有</strong> 实例(<code><span style="font-size: small;">!:gs</span></code> 表示 “全局替换[global substitution]”)。 </li>
<li>
<code><span style="font-size: small;">!-2</span></code> 是倒数第二条命令,<code><span style="font-size: small;">!-3</span></code> 是倒数第三条命令,以此类推。 </li>
</ul>
<p>您甚至可以合并历史表达式来生成 <code><span style="font-size: small;">!-2:0 -R !^ !-3:2</span></code> 这样的 “魔汤”,该命令将扩展为倒数第二条命令的名称,加上 <code><span style="font-size: small;">-R</span></code>,再加上前一条命令的第一个参数,以及倒数第三条命令的第二个参数。要使这样的神秘命令更具可读性,可以在键入时扩展历史参考。在任意提示符键入命令 <code><span style="font-size: small;">bind Space:magic-space</span></code> ,或者将其添加到一个启动文件,从而将空格键绑定到函数 magic-space,该函数将扩展内联历史替换。 </p>
<div class="ibm-alternate-rule">
<hr>
</div>
<p><a name="expand"></a></p>
<p>鉴于 Internet 上有如此众多的代码,您可能每天都会下载数十个文件。可能会出现这样的情况:所有那些文件都使用不同的方式打包 — 有的是 ZIP 文件,有的是 RAR 文件,还有很多是 tarball 文件,尽管每个包都使用不同的实用程序压缩。记住如何解压缩和扩展每种包格式将会使人精疲力尽。那么,为何不在单个命令中完成所有那些任务呢?下面这个函数在许多样例点文件中广泛可用: </p>
<table style="width: 65%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycode">ex () {
if [ -f $1 ] ; then
case $1 in
*.tar.bz2) tar xjf $1 ;;
*.tar.gz) tar xzf $1 ;;
*.bz2) bunzip2 $1 ;;
*.rar) rar x $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar xf $1 ;;
*.tbz2) tar xjf $1 ;;
*.tgz) tar xzf $1 ;;
*.zip) unzip $1 ;;
*.Z) uncompress $1 ;;
*.7z) 7z x $1 ;;
*) echo "'$1' cannot be extracted via extract()" ;;
esac
else
echo "'$1' is not a valid file"
fi
}
</pre>
</td>
</tr></tbody></table>
<br><p>这个函数 <code><span style="font-size: small;">ex</span></code> 扩展了 11 种文件格式;如果要处理其他包类型,该函数还可以扩展。一旦定义 — 例如,在一个 shell 启动文件中 — 就可以简单地键入 <code><span style="font-size: small;">ex <strong>somefile</strong></span></code>,其中 <code><strong><span style="font-size: small;">somefile</span></strong></code> 以以下一种已命名扩展结束: </p>
<table style="width: 65%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycode">$ ls
source
$ tar czf source.tgz source
$ ls -1
source
source.tgz
$ rm -rf source
$ ex source.tgz
$ ls -1
source
source.tgz
</pre>
</td>
</tr></tbody></table>
<br><p>顺便说一下,如果您将今天下载的文件放错了位置,可以运行 <code><span style="font-size: small;">find</span></code> 来查找它: </p>
<table style="width: 65%;" border="0" cellspacing="0" cellpadding="0"><tbody><tr>
<td class="code-outline">
<pre class="displaycode">$ find ~ -type f -mtime 0
</pre>
</td>
</tr></tbody></table>
<br><p>命令 <code><span style="font-size: small;">-type f</span></code> 查找纯文本文件,<code><span style="font-size: small;">-mtime 0</span></code> 查找自当天午夜以来创建的文件。 </p>
<div class="ibm-alternate-rule">
<hr>
</div>
<p><a name="moresecrets"></a></p>
<p>需要揭开的专家秘密还有很多。在 Web 上搜索 “shell auto-complete”,进一步了解自动完成特性,该特性用于在您键入一条命令时提供上下文敏感的扩展。另外,搜索 “shell prompts” 以了解如何定制您的 shell 提示:可以将其设置为彩色,可以设置您的当前工作目录或 Git 分支,还可以显示历史数目 — 如果经常调用历史,这是一个方便的参考信息。要查看工作示例,可在 Github 中搜索 “dot files”。许多专家都将他们的 shell 配置张贴在 Github 上。</p>
</div>
</div>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值