在Linux中克隆WordPress

最终产品图片
您将要创造的

复制WordPress从未如此简单

我经常喜欢以现有网站为模板启动一个新的WordPress网站。 主题,插件和设置的配置从一开始就非常有用,与全新安装相反,您必须从头开始重复所有操作。

在“ 构建要在Digital Ocean上转售的应用程序映像”中,我完成了可安装,预配置和预优化的WordPress小滴的构建。 本质上,它是一个数字海洋映像,可以在几分钟内启动一个完全加载的WordPress网站。 但是,更常见的是,我想将WordPress网站添加到我自己的现有服务器中。

有很多方法可以做到这一点,但是我经常发现它们需要一种具体而详细的方法,我似乎每次都必须重新学习。 我认为是时候提出一个Linux shell脚本了,它将在几分钟内为我完成所有工作。

在本教程中,我将引导您完成我的研究工作以及由此产生的WordPress克隆脚本。 我希望你喜欢它-我认为完成后效果很好。

在开始之前,请记住,我确实会尝试参加以下讨论。 如果您有任何问题或建议,请在下面发表评论,或通过Twitter @reifman与我联系 。 您也可以直接给我发电子邮件 。 我希望你们中的许多人会对这个脚本有更好的想法和改进。 多谢您的来信。

WordPress迁移的其他方法

通常,您可以通过以下方式来启动新网站:将现有网站迁移到新服务器,从本质上进行复制,然后在副本上构建文件,同时保持源站点完整。 有很多方法可以解决这个问题。

在使用WordPress将WordPress迁移到新的Server Publishing中 ,我写了关于使用Duplicator插件执行此操作的信息-但我发现该过程很麻烦。 每次我需要移动网站时,都要使自己不熟悉Duplicator。

最近,我在使用CodeGuard for Envato Tuts + 备份和还原WordPress网站中撰写了有关此内容。 这项服务使此过程更加容易。 并且,很快,将发布如何简化管理多个WordPress网站的过程 ,描述了使用ManageWP的许多强大优势。 它具有克隆功能,但需要FTP-出于安全原因,我避免在服务器上运行FTP。

还有的两部分的Envato Tuts +系列: 移动WordPress:简介移动WordPress:使用插件移动您的网站WPBeginner上有使用BackupBuddy的教程 。 最后, WPClone不需要FTP,但需要在其上进行干净的WordPress安装。

您可以从所有这些教程和服务中学到很多东西,但是我想看看是否可以创建一个命令行脚本来每次更快速,更轻松地克隆WordPress网站。

规划脚本

在撰写本教程时,我非常依赖其他人的早期作品来快速掌握bash脚本和WordPress网站操作的知识。 我从未考虑过自己是Linux系统专家。 最终,我决定在Brian GallagherWordPress Bash安装脚本之上构建克隆脚本。

注意: 这些是基于Debian的安装脚本; 其他Linux版本(例如RedHat和CentOS)对于Apache和不同的实用程序具有不同的路径。

这是加拉格尔对他的基本脚本的描述:

下载最新的WP版本,使用用户提供的数据库名称,用户名和密码更新wp-config,创建并创建CHMOD的上载目录,将所有文件复制到运行脚本的根目录中,然后删除自身!

首先有很多组织良好的脚本,但是我想制作一些可以克隆活动站点的脚本。 让我们回顾一下典型的WordPress配置的体系结构。

WordPress网站的初始组件

典型的WordPress安装具有四个主要的克隆组件:

  1. 网站的目录树
  2. 数据库
  3. Web服务器配置,例如Apache conf文件
  4. 域映射

我们还需要一些信息,访问权限和安全设置:

  • 服务器管理帐户和密码
  • MySql服务器的用户名和密码
  • 网站的源目录
  • 网站的Web服务器配置文件
  • 数据库名称,用户名和密码

这是我们需要为克隆站点指定的内容:

  • 克隆站点的目标目录
  • 克隆的数据库名称,用户名和密码
  • 克隆站点的Web服务器配置文件

脚本需要做什么

  • 通过配置变量或用户输入获取所有设置。
  • 复制站点目录并将其还原到目标目录。
  • 导出源数据库并将其导入到目标数据库。
  • 确保对这些目录具有适当的权限。
  • 复制服务器配置文件并更新域和目录设置。
  • 重新加载Web服务器。

手动地,我们必须为新的目标域更新DNS。 我建议您在开始之前创建DNS记录,以便在克隆站点后就可以使用它们。 没有什么比克隆站点和因为等待DNS而无法测试域名了。

克隆脚本的方法

现在,我们准备逐步了解脚本的架构。 再次,我首先利用了Gallagher的WordPress安装脚本,并且您需要在顶部使用初始bash行:

#!/bin/bash -e
# Clone a WordPress site via Bash script
clear
echo "==================================================="
echo "Clone WordPress Script"
echo "==================================================="

准备DNS设置

复制站点之前,需要为克隆的站点配置DNS。 您可以在此处阅读有关新WordPress网站的DNS配置的信息 。 我也对Envato Tuts +教程“ 学习和使用DNS记录简介”感到兴奋。

基本上,您需要创建一个A记录或CNAME,将所需的克隆URL路由到我们要复制的服务器上。

设置权限

在我的服务器上,我正在创建一个名为clonewp.sh的bash脚本。 它将需要可执行权限:

chmod +x clonewp.sh

然后,一旦完成,就可以像这样运行它:

sudo bash clonewp.sh

我建议以sudo身份运行脚本,这样就不会遇到文件权限问题。

设置默认值

为了进行测试,我创建了使用默认设置预加载脚本的功能。 它帮助我反复进行测试,而不必一遍又一遍地键入所有内容。 我还认为,这对于以后想要修改脚本或以其他方式使用脚本的人可能很有用。

以下是所有默认设置:

# Set Default Settings (helpful for testing)
default_mysql_user=$"root-admin"
default_mysql_pass=$"super-strong-password"
default_source_domain=$"gardening.io"
default_target_domain=$"cycling.io"
default_source_directory=$"/var/www/gardening"
default_target_directory=$"/var/www/cycling"
default_apache_directory=$"/etc/apache2/sites-available"
default_source_conf=$"gardening.conf"
default_target_conf=$"cycling.conf"
default_source_dbname=$"gardening"
default_source_dbuser=$"user_for_garden"
default_source_dbpass=$"pwd_garden"
default_target_dbname=$"cycling"
default_target_dbuser=$"user_for_cycling"
default_target_dbpass=$"pwd_cycling"
NOW=$(date +"%Y-%m-%d-%H%M")

我知道这看起来很多,但是我发现拥有一个MySQL主用户和密码来进行数据库备份,数据库创建和导入很有用。 但是,在wp-config.php文件中使用特定于站点的数据库用户和密码来设置目标数据库特权以及进行搜索和替换也很有用。 它使最终克隆过程变得非常无缝。

我使用NOW时间戳来确保我们创建的档案是唯一的。

要求设置

以下代码向用户显示默认值,并允许他们接受(按回车键)或替换它:

# Request Source Settings
read -p "Source Domain (e.g. "$default_source_domain"): " source_domain
source_domain=${source_domain:-$default_source_domain}
echo $source_domain
read -p "Source Directory (no trailing slash e.g. "$default_source_directory"): " source_directory
source_directory=${source_directory:-$default_source_directory}
echo $source_directory
read -p "Source Database Name (e.g. "$default_source_dbname"): " source_dbname
source_dbname=${source_dbname:-$default_source_dbname}
echo $source_dbname
read -p "Source Database User (e.g. "$default_source_dbuser"): " source_dbuser
source_dbuser=${source_dbuser:-$default_source_dbuser}
echo $source_dbuser
read -p "Source Database Pass (e.g. "$default_source_dbpass"): " source_dbpass
source_dbpass=${source_dbpass:-$default_source_dbpass}
echo $source_dbpass
# Request Source Settings
read -p "Source Conf File (e.g. "$default_source_conf"): " source_conf
source_conf=${source_conf:-$default_source_conf}
echo $source_conf
# Request Target Settings
read -p "Target Domain (e.g. "$default_target_domain"): " target_domain
target_domain=${target_domain:-$default_target_domain}
echo $target_domain
read -p "Target Directory (no trailing slash e.g. "$default_target_directory"): " target_directory
target_directory=${target_directory:-$default_target_directory}
echo $target_directory
read -p "Target Database Name (e.g. "$default_target_dbname"): " target_dbname
target_dbname=${target_dbname:-$default_target_dbname}
echo $target_dbname
read -p "Target Database User (e.g. "$default_target_dbuser"): " target_dbuser
target_dbuser=${target_dbuser:-$default_target_dbuser}
echo $target_dbuser
read -p "Target Database Pass (e.g. "$default_target_dbpass"): " target_dbpass
target_dbpass=${target_dbpass:-$default_target_dbpass}
echo $target_dbpass
read -p "Target Conf File (e.g. "$default_target_conf"): " target_conf
target_conf=${target_conf:-$default_target_conf}
echo $target_conf

从用户那里收集了所有设置后,我们询问他们是否希望开始:

echo "Clone now? (y/n)"
read -e run
if [ "$run" == n ] ; then
exit
else
echo "==================================================="
echo "WordPress Cloning is Beginning"
echo "==================================================="

复制目录树

现在事情进展得更快了。 我们创建源站点的tarball,创建目标目录并在其中解压缩tarball:

#backup source_directory
cd $source_directory
# add -v option to these if you want to see verbose file listings
tar -czf source_clone_$NOW.tar.gz .
#unzip clone in target directory
mkdir -p $target_directory
tar -xzf source_clone_$NOW.tar.gz -C $target_directory
#remove tarball of source
rm source_clone_$NOW.tar.gz
cd $target_directory

我们还为WordPress运行标准文件权限,以确保所有内容均已正确且安全地设置:

# Reset Directory Permissions
find $target_directory -type d -exec chmod 755 {} \;
find $target_directory -type f -exec chmod 644 {} \;

更新WP-Config文件

接下来,我们使用perl搜索源数据库身份验证并将其替换为目标数据库信息:

#set database details with perl find and replace
perl -pi -e "s/$source_dbname/$target_dbname/g" wp-config.php
perl -pi -e "s/$source_dbuser/$target_dbuser/g" wp-config.php
perl -pi -e "s/$source_dbpass/$target_dbpass/g" wp-config.php
echo "define('RELOCATE',true);" | tee -a wp-config.php
#echo "define('WP_HOME','http://$target_domain');" | tee -a wp-config.php
#echo "define('WP_SITEURL','http://$target_domain');" | tee -a wp-config.php
echo "================================"
echo "Directory duplicated"
echo "================================"

我还将RELOCATE设置添加到文件的末尾。 如果愿意,可以将其替换为静态WP_HOMEWP_SITEURL设置。

复制数据库

接下来,我们转储数据库,使用用户提供的权限创建一个新数据库,然后将数据库导入到其中:

# Begin Database Duplication
# Export the database
mysqldump -u$mysql_user -p$mysql_pass $source_dbname > $target_directory/clone_$NOW.sql
# Create the target database and permissions
mysql -u$mysql_user -p$mysql_pass -e "create database $target_dbname; GRANT ALL PRIVILEGES ON $target_dbname.* TO '$target_dbuser'@'localhost' IDENTIFIED BY '$target_dbpass'"
# Import the source database into the target
mysql -u$mysql_user -p$mysql_pass $target_dbname < $target_directory/clone_$NOW.sql
echo "================================"
echo "Database duplicated"
echo "================================"

再次,我发现最好根据这些活动使用主MySQL身份验证,同时基于源站点和单站点克隆设置配置数据库设置。

复制Web服务器配置

最后,我们准备结束一切,然后按启动按钮。 我很少看到这类脚本管理Web服务器配置的额外步骤。 所以,我也想这样做。

我将源站点的Apache .conf文件复制到克隆的新.conf文件中。 我用perl替换了域和目录路径的字符串。 然后,我使用Apache激活了该站点并重新加载了Web服务器:

#Activate Web Configuration
cp $default_apache_directory/$source_conf $default_apache_directory/$target_conf
#set database details with perl find and replace
perl -pi -e "s/$source_domain/$target_domain/g" $default_apache_directory/$target_conf
perl -pi -e "s|${source_directory}|${target_directory}|g" $default_apache_directory/$target_conf
a2ensite $target_conf
service apache2 reload
echo "================================"
echo "Web configuration added"
echo "================================"
echo "Clone is complete."
echo "Test at http://"$target_domain
echo "================================"
fi

就是这样。 在现实生活中,脚本的运行过程如下所示:

===================================================
Clone WordPress Script
===================================================
MySQL Master Username (e.g. root-admin): harry_potter
harry_potter
MySQL Master Password (e.g. super-strong-password): voldemoort~jenny7!
voldemoort~jenny7!
Source Domain (e.g. gardening.io): 
gardening.io
Source Directory (no trailing slash e.g. /var/www/gardening): 
/var/www/gardening
Source Database Name (e.g. gardening): database_gardening
database_gardening
Source Database User (e.g. user_for_garden): hermione
hermione
Source Database Pass (e.g. pwd_garden): !987654321abcdefgh#
!987654321abcdefgh#
Source Conf File (e.g. gardening.conf): gardening.conf
gardening.conf
Target Domain (e.g. cycling.io): 
cycling.io
Target Directory (no trailing slash e.g. /var/www/cycling): /var/www/cycling
/var/www/cycling
Target Database Name (e.g. cycling): database_cycling
database_cycling
Target Database User (e.g. user_for_cycling): hedwig
hedwig
Target Database Pass (e.g. pwd_cycling): 
pwd_for_cycling_not_hogwartz
Target Conf File (e.g. cycling.conf): 0007b-cycling.conf               
0007b-cycling.conf
Clone now? (y/n)
y
===================================================
WordPress Cloning is Beginning
===================================================
tar: .: file changed as we read it
define('RELOCATE',true);
================================
Directory duplicated
================================
================================
Database duplicated
================================
Enabling site 0007b-cycling.
To activate the new configuration, you need to run:
  service apache2 reload
 * Reloading web server apache2                                                                                     * 
================================
Web configuration added
================================
Clone is complete.
Test at http://cycling.io
================================

在我的小型WordPress网站上,复制只花了30到90秒!

印刷精美

您还需要了解几件事。

首先直接登录路径

首先,要登录到克隆的站点,您需要使用wp-login.php路径而不是wp-admin路径,它会重定向到源站点URL,例如http://clone.io/wp-login.php如下所示:

克隆WordPress使用wp-login php路径
变更网域

由于WordPress在数据库中对大部分源域进行了硬编码,因此我发现使用wp-config.php中的RELOCATE设置可以很容易地通过General> Settings来更新它。 您只需使用新的目标URL保存表单:

克隆WordPress常规域设置

保存克隆的目标URL后,可以从wp-config.php中手动删除RELOCATE设置。

但是,一位同事建议您可能要使用诸如InterconnectIT的Search and Replace for WordPress Databases之类的工具 。 Envato Tuts +中的《 跨主机,服务器和URL迁移WordPress》中也对此进行了记录。

最终剧本

这是wpclone.sh的最终脚本,可以随意更改默认值:

#!/bin/bash -e
# Clone a WordPress site via Bash script
clear
echo "==================================================="
echo "Clone WordPress Script"
echo "==================================================="
# Set Default Settings (helpful for testing)
default_mysql_user=$"root-admin"
default_mysql_pass=$"super-strong-password"
default_source_domain=$"gardening.io"
default_target_domain=$"cycling.io"
default_source_directory=$"/var/www/gardening"
default_target_directory=$"/var/www/cycling"
default_apache_directory=$"/etc/apache2/sites-available"
default_source_conf=$"gardening.conf"
default_target_conf=$"cycling.conf"
default_source_dbname=$"gardening"
default_source_dbuser=$"user_for_garden"
default_source_dbpass=$"pwd_garden"
default_target_dbname=$"cycling"
default_target_dbuser=$"user_for_cycling"
default_target_dbpass=$"pwd_cycling"
NOW=$(date +"%Y-%m-%d-%H%M")

#Request MySQL Admin
read -p "MySQL Master Username (e.g. "$default_mysql_user"): " mysql_user
mysql_user=${mysql_user:-$default_mysql_user}
echo $mysql_user
read -p "MySQL Master Password (e.g. "$default_mysql_pass"): " mysql_pass
mysql_pass=${mysql_pass:-$default_mysql_pass}
echo $mysql_pass

# Request Source Settings
read -p "Source Domain (e.g. "$default_source_domain"): " source_domain
source_domain=${source_domain:-$default_source_domain}
echo $source_domain
read -p "Source Directory (no trailing slash e.g. "$default_source_directory"): " source_directory
source_directory=${source_directory:-$default_source_directory}
echo $source_directory
read -p "Source Database Name (e.g. "$default_source_dbname"): " source_dbname
source_dbname=${source_dbname:-$default_source_dbname}
echo $source_dbname
read -p "Source Database User (e.g. "$default_source_dbuser"): " source_dbuser
source_dbuser=${source_dbuser:-$default_source_dbuser}
echo $source_dbuser
read -p "Source Database Pass (e.g. "$default_source_dbpass"): " source_dbpass
source_dbpass=${source_dbpass:-$default_source_dbpass}
echo $source_dbpass
# Request Source Settings
read -p "Source Conf File (e.g. "$default_source_conf"): " source_conf
source_conf=${source_conf:-$default_source_conf}
echo $source_conf
# Request Target Settings
read -p "Target Domain (e.g. "$default_target_domain"): " target_domain
target_domain=${target_domain:-$default_target_domain}
echo $target_domain
read -p "Target Directory (no trailing slash e.g. "$default_target_directory"): " target_directory
target_directory=${target_directory:-$default_target_directory}
echo $target_directory
read -p "Target Database Name (e.g. "$default_target_dbname"): " target_dbname
target_dbname=${target_dbname:-$default_target_dbname}
echo $target_dbname
read -p "Target Database User (e.g. "$default_target_dbuser"): " target_dbuser
target_dbuser=${target_dbuser:-$default_target_dbuser}
echo $target_dbuser
read -p "Target Database Pass (e.g. "$default_target_dbpass"): " target_dbpass
target_dbpass=${target_dbpass:-$default_target_dbpass}
echo $target_dbpass
read -p "Target Conf File (e.g. "$default_target_conf"): " target_conf
target_conf=${target_conf:-$default_target_conf}
echo $target_conf
echo "Clone now? (y/n)"
read -e run
if [ "$run" == n ] ; then
exit
else
echo "==================================================="
echo "WordPress Cloning is Beginning"
echo "==================================================="
#backup source_directory
cd $source_directory
# add -v option to these if you want to see verbose file listings
tar -czf source_clone_$NOW.tar.gz .
#unzip clone in target directory
mkdir -p $target_directory
tar -xzf source_clone_$NOW.tar.gz -C $target_directory
#remove tarball of source
rm source_clone_$NOW.tar.gz
cd $target_directory
# Reset Directory Permissions
find $target_directory -type d -exec chmod 755 {} \;
find $target_directory -type f -exec chmod 644 {} \;
#set database details with perl find and replace
perl -pi -e "s/$source_dbname/$target_dbname/g" wp-config.php
perl -pi -e "s/$source_dbuser/$target_dbuser/g" wp-config.php
perl -pi -e "s/$source_dbpass/$target_dbpass/g" wp-config.php
echo "define('RELOCATE',true);" | tee -a wp-config.php
#echo "define('WP_HOME','http://$target_domain');" | tee -a wp-config.php
#echo "define('WP_SITEURL','http://$target_domain');" | tee -a wp-config.php
echo "================================"
echo "Directory duplicated"
echo "================================"
# Begin Database Duplication
# Export the database
mysqldump -u$mysql_user -p$mysql_pass $source_dbname > $target_directory/clone_$NOW.sql
# Create the target database and permissions
mysql -u$mysql_user -p$mysql_pass -e "create database $target_dbname; GRANT ALL PRIVILEGES ON $target_dbname.* TO '$target_dbuser'@'localhost' IDENTIFIED BY '$target_dbpass'"
# Import the source database into the target
mysql -u$mysql_user -p$mysql_pass $target_dbname < $target_directory/clone_$NOW.sql
echo "================================"
echo "Database duplicated"
echo "================================"
#Activate Web Configuration
cp $default_apache_directory/$source_conf $default_apache_directory/$target_conf
#set database details with perl find and replace
perl -pi -e "s/$source_domain/$target_domain/g" $default_apache_directory/$target_conf
perl -pi -e "s|${source_directory}|${target_directory}|g" $default_apache_directory/$target_conf
a2ensite $target_conf
service apache2 reload
echo "================================"
echo "Web configuration added"
echo "================================"
echo "Clone is complete."
echo "Test at http://"$target_domain
echo "================================"
fi

如果您有建议和自定义,请告诉我。 在下面的评论中发表您的想法。

清理以进行扩展测试

以下几行可能对删除和撤消克隆的测试站点有帮助。 您可以根据需要自定义它:

sudo rm -ifr /var/www/clone
  sudo a2dissite clone.conf 
  sudo service apache2 reload
  sudo rm /etc/apache2/sites-available/clone.conf
  mysql -u root -p -e "drop database clone;"
更改Wp-Config.php中的安全密钥

您还可以通过手动替换目标站点的wp-config.php中的身份验证密钥和盐来更好地保护新的WordPress站点:

/**#@+
 * Authentication Unique Keys and Salts.
 *
 * Change these to different unique phrases!
 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key 
service}
 * You can change these at any point in time to invalidate all existing cookies. This will force all users to have 
to log in again.
 *
 * @since 2.6.0
 */
define('AUTH_KEY',         '+9%S?YVnr%5Vr!Et4J,@9/Z^.kT_Lu~5SGwr9=|Y &D-ARSWf$mF#J_3U:/iE>-R');
define('SECURE_AUTH_KEY',  'e3Wr7%Aa7H1,f<SR[Sp&g.kJw,.)bR-9jz{uU&[R{[J]ITK8q>:!5@y:Q;c01dL ');
define('LOGGED_IN_KEY',    '1I%pW%UyjRMqy__Da)siA)+V]Ur$9uXPmxv|eBjM~-m&-<WEy&+XXb43uh8&aP+U');
define('NONCE_KEY',        'A9]+PFgvxYa^<B}_.F?9A,!&i-.b6E.I?&?U*)X.Vh+fq`SfE[XJG+MG|pg;y%Ah');
define('AUTH_SALT',        'gT (4]L{mm!|>9kC<%59rB7sbe1)jW0GCnfupJT+8z-z#%o@b|[QH=i@h|-/t!9S');
define('SECURE_AUTH_SALT', 'ON8K<,WSy8+F ~XaQpCwC8(a/{HksMh<T)QLD]s[-:yv+fx8!`<!*~mgB32X:w5k');
define('LOGGED_IN_SALT',   'vHJ%{=X6$ue>ZIo|%|cisp1R}9cJ< Rz-J;H|:O2A7$+*aGXMH!+KvD+tZ/I*U5$');
define('NONCE_SALT',       '[ytQ;C)BvgU!#>a,,g|)~EKBQUig7Uv.-8?q%lmFte,P>,]f#.}i`Wx8S+_S@&.(');
/**#@-*/

您可以只访问https://api.wordpress.org/secret-key/1.1/salt/并将其剪切并粘贴到wp-config.php文件中:

WordPress身份验证密钥和盐生成器

现在,如果您是Linux脚本的纯粹主义者,我将让您更新Gallagher的WordPress Bash安装脚本 。 他的脚本复制了默认的WordPress wp-config.php,因此他将拥有可预测的源字符串,以其脚本生成的密钥替换:

#set WP salts
perl -i -pe'
  BEGIN {
    @chars = ("a" .. "z", "A" .. "Z", 0 .. 9);
    push @chars, split //, "!@#$%^&*()-_ []{}<>~\`+=,.;:/?|";
    sub salt { join "", map $chars[ rand @chars ], 1 .. 64 }
  }
  s/put your unique phrase here/salt()/ge
' wp-config.php

我从未写过一个正则表达式来替换源站点中动态存在的wp-config.php文件中的键值。 如果您决定,请在评论中分享它,并预先感谢。

有什么问题吗

我非常喜欢这个脚本的工作。 或者,我至少应该说完成后喜欢运行它。 我希望我能在很久以前创建它,因为它非常有效。 我可以克隆小型WordPress网站,并使它们在大约60秒内在我的服务器上运行。 其他插件或复制选项都不是无缝的。

如有疑问,请在下面发布。 或者,您可以通过Twitter @reifman与我联系或直接给我发送电子邮件 。 请查看我的Envato Tuts +讲师页面,以查看我编写的其他教程,例如我的启动系列( 使用PHP构建您的启动 )。

相关链接

翻译自: https://code.tutsplus.com/tutorials/clone-wordpress-in-linux--cms-25059

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值