• 150455

    文章

  • 1009

    评论

  • 13

    友链

  • 最近新加了换肤功能,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

第六课:《Linux就该这么学》课堂笔记


“工作马马虎虎,只想在兴趣和游戏中寻觅快活,充其量只能获得一时的快感,绝不能尝到从心底涌出的惊喜和快乐,但来自工作的喜悦并不像糖果那样—放进嘴里就甜味十足,而是需要从苦劳与艰辛中渗出,因此当我们聚精会神,孜孜不倦,克服艰辛后的成就感,世上没有哪种喜悦可以类比”。——稻盛和夫

“更何况人类生活中工作占据了较大的比重,如果不能从劳动中、工作中获得充实感,那么即使从别的地方找到快乐,最终我们仍然会感到空虚和缺憾”。——稻盛和夫

————————————————————————————————————————

蓝色字体:需要输入的命令

红色字体:重点关注的解释和说明 

学习重点: 

3.3  while条件循环语句

while条件循环语句是一种让脚本根据某些条件来重复执行命令的语句,它的循环结构往往在执行前并不确定最终执行的次数,完全不同于for循环语句中有目标、有范围的使用场景。while循环语句通过判断条件测试的真假来决定是否继续执行命令,若条件为继续执行,为结束循环while语句的语法格式如图4-21所示。

4-21  while循环语句的语法格式

接下来结合使用多分支的if条件测试语句与while条件循环语句,编写一个用来猜测数值大小的脚本Guess.sh。该脚本使用$RANDOM变量来调取出一个随机的数值(范围为032767),将这个随机数对1000进行取余操作,并使用expr命令取得其结果,再用这个数值与用户通过read命令输入的数值进行比较判断。这个判断语句分为三种情况,分别是判断用户输入的数值是等于、大于还是小于使用expr命令取得的数值。当前,现在这些内容不是重点,我们当前要关注的是while条件循环语句中的条件测试始终为true,因此判断语句会无限执行下去,直到用户输入的数值等于expr命令取得的数值后,这两者相等之后才运行exit 0命令,终止脚本的执行。

[root@linuxprobe ~]# vim Guess.sh 创建名为Cuess.sh的一个Shee脚本

#!/bin/bash   编辑脚本的声明

PRICE=$(expr $RANDOM % 1000) 

TIMES=0

echo "商品实际价格为0-999之间,猜猜看是多少?"

while true

do

read -p "请输入您猜测的价格数目:" INT

let TIMES++

if [ $INT -eq $PRICE ] ; then

echo "恭喜您答对了,实际价格是 $PRICE"

echo "您总共猜g $TIMES 次"

exit 0

elif [ $INT -gt $PRICE ] ; then

echo "太高了!"

else

echo "太低了!"

fi

done

 

在这个Guess.sh脚本中,我们添加了一些交互式的信息,从而使得用户与系统的互动性得以增强。而且每当循环到let TIMES++命令时都会让TIMES变量内的数值加1,用来统计循环总计执行了多少次。这可以让用户得知总共猜测了多少次之后,才猜对价格。

 

[root@linuxprobe ~]# bash Guess.sh

商品实际价格为0-999之间,猜猜看是多少?

请输入您猜测的价格数目:500

太低了!

请输入您猜测的价格数目:800

太高了!

请输入您猜测的价格数目:650

太低了!

请输入您猜测的价格数目:720

太高了!

请输入您猜测的价格数目:690

太低了!

请输入您猜测的价格数目:700

太高了!

请输入您猜测的价格数目:695

太高了!

请输入您猜测的价格数目:692

太高了!

请输入您猜测的价格数目:691

恭喜您答对了,实际价格是 691

您总共猜测了 9 

 

4.3.4  case条件测试语句

如果您之前学习过C语言,看到这一小节的标题肯定会会心一笑“这不就是switch语句嘛!”是的,case条件测试语句和switch语句的功能非常相似!case语句是在多个范围内匹配数据,若匹配成功则执行相关命令并结束整个条件测试;而如果数据不在所列出的范围内,则会去执行星号(*)中所定义的默认命令。case语句的语法结构如图4-22所示。

4-22  case条件测试语句的语法结构

在前文介绍的Guess.sh脚本中有一个致命的弱点—只能接受数字!您可以尝试输入一个字母,会发现脚本立即就崩溃了。原因是字母无法与数字进行大小比较,例如,“a是否大于等于3”这样的命题是完全错误的。我们必须有一定的措施来判断用户的输入内容,当用户输入的内容不是数字时,脚本能予以提示,从而免于崩溃。

通过在脚本中组合使用case条件测试语句和通配符(详见第3章),完全可以满足这里的需求。接下来我们编写脚本Checkkeys.sh,提示用户输入一个字符并将其赋值给变量KEY,然后根据变量KEY的值向用户显示其值是字母、数字还是其他字符。

[root@linuxprobe ~]# vim Checkkeys.sh

#!/bin/bash

read -p "请输入一个字符,并按Enter键确认:" KEY

case "$KEY" in

[a-z]|[A-Z])

echo "您输入的是 字母。"

;;

[0-9])

echo "您输入的是 数字。"

;;

*)

echo "您输入的是 空格、功能键或其他控制字符。"

esac

[root@linuxprobe ~]# bash Checkkeys.sh

请输入一个字符,并按Enter键确认:6

您输入的是 数字。

[root@linuxprobe ~]# bash Checkkeys.sh

请输入一个字符,并按Enter键确认:p

您输入的是 字母。

[root@linuxprobe ~]# bash Checkkeys.sh

请输入一个字符,并按Enter键确认:^[[15~

您输入的是 空格、功能键或其他控制字符。

4.4  计划任务服务程序

经验丰富的系统运维工程师可以使得Linux在无需人为介入的情况下,在指定的时间段自动启用或停止某些服务或命令,从而实现运维的自动化。尽管我们现在已经有了功能彪悍的脚本程序来执行一些批处理工作,但是,如果仍然需要在每天凌晨两点敲击键盘回车键来执行这个脚本程序,这简直太痛苦了(当然,也可以训练您的小猫在半夜按下回车键)。接下来,刘遄老师将向大家讲解如何设置服务器的计划任务服务,把周期性、规律性的工作交给系统自动完成。

计划任务分为一次性计划任务与长期性计划任务,大家可以按照如下方式理解。

Ø   一次性计划任务:今晚1130分开启网站服务。

Ø   长期性计划任务:每周一的凌晨325分把/home/wwwroot目录打包备份为backup.tar.gz

顾名思义,一次性计划任务只执行一次,一般用于满足临时的工作需求。我们可以用at命令实现这种功能,只需要写成“at 时间”的形式就可以。如果想要查看已设置好但还未执行的一次性计划任务,可以使用“at -l”命令;要想将其删除,可以用“atrm 任务序号”。在使用at命令来设置一次性计划任务时,默认采用的是交互式方法。例如,使用下述命令将系统设置为在今晚23:30分自动重启网站服务。

[root@linuxprobe ~]# at 23:30

at > systemctl restart httpd

at > 此处请同时按下Ctrl + D组合键来结束编写计划任务

job 3 at Mon Apr 27 23:30:00 2017

[root@linuxprobe ~]# at -l

3 Mon Apr 27 23:30:00 2017 a root

 

如果读者想挑战一下难度更大但简捷性更高的方式,可以把前面学习的管道符(任意门)放到两条命令之间,让at命令接收前面echo命令的输出信息,以达到通过非交互式的方式创建计划一次性任务的目的。

 

[root@linuxprobe ~]# echo "systemctl restart httpd" | at 23:30

job 4 at Mon Apr 27 23:30:00 2017

[root@linuxprobe ~]# at -l

3 Mon Apr 27 23:30:00 2017 a root

4 Mon Apr 27 23:30:00 2017 a root

 

如果我们不小心设置了两个一次性计划任务,可以使用下面的命令轻松删除其中一个:

 

[root@linuxprobe ~]# atrm 3

[root@linuxprobe ~]# at -l

4 Mon Apr 27 23:30:00 2017 a root

 

如果我们希望Linux系统能够周期性地、有规律地执行某些具体的任务,那么Linux系统中默认启用的crond服务简直再适合不过了。创建、编辑计划任务的命令为“crontab -e”,查看当前计划任务的命令为“crontab -l”,删除某条计划任务的命令为“crontab -r”。另外,如果您是以管理员的身份登录的系统,还可以在crontab命令中加上-u参数来编辑他人的计划任务。

在正式部署计划任务前,请先跟刘遄老师念一下口诀“分、时、日、月、星期 命令”。这是使用crond服务设置任务的参数格式(其格式见表4-6)。需要注意的是,如果有些字段没有设置,则需要使用星号(*)占位,如图4-23所示。

4-23  使用crond设置任务的参数格式

4-6                                         使用crond设置任务的参数字段说明

字段

说明

取值为059的整数

取值为023的任意整数

取值为131的任意整数

取值为112的任意整数

星期

取值为07的任意整数,其中07均为星期日

命令

要执行的命令或程序脚本

 

假设在每周一、三、五的凌晨325分,都需要使用tar命令把某个网站的数据目录进行打包处理,使其作为一个备份文件。我们可以使用crontab -e命令来创建计划任务。为自己创建计划任务无需使用-u参数,具体的实现效果的参数如crontab -l命令结果所示:

 

[root@linuxprobe ~]# crontab -e

no crontab for root - using an empty one

crontab: installing new crontab

[root@linuxprobe ~]# crontab -l

25 3 * * 1,3,5 /usr/bin/tar -czvf backup.tar.gz /home/wwwroot

 

需要说明的是,除了用逗号(,)来分别表示多个时间段,例如“8,9,12”表示8月、9月和12月。还可以用减号(-)来表示一段连续的时间周期(例如字段“日”的取值为“12-15”,则表示每月的1215日)。以及用除号(/)表示执行任务的间隔时间(例如“*/2”表示每隔2分钟执行一次任务)。

如果在crond服务中需要同时包含多条计划任务的命令语句,应每行仅写一条。例如我们再添加一条计划任务,它的功能是每周一至周五的凌晨1点钟自动清空/tmp目录内的所有文件。尤其需要注意的是,在crond服务的计划任务参数中,所有命令一定要用绝对路径的方式来写,如果不知道绝对路径,请用whereis命令进行查询,rm命令路径为下面输出信息中加粗部分。

 

[root@linuxprobe ~]# whereis rm

rm: /usr/bin/rm /usr/share/man/man1/rm.1.gz /usr/share/man/man1p/rm.1p.gz

[root@linuxprobe ~]# crontab -e

crontab: installing new crontab

[root@linuxprobe ~]# crontab -l

25 3 * * 1,3,5 /usr/bin/tar -czvf backup.tar.gz /home/wwwroot

0 1 * * 1-5 /usr/bin/rm -rf /tmp/*

 

在本节最后,刘遄老师再来啰嗦几句在工作中使用计划服务的注意事项。

Ø   crond服务的配置参数中,可以像Shell脚本那样以#号开头写上注释信息,这样在日后回顾这段命令代码时可以快速了解其功能、需求以及编写人员等重要信息。

Ø   计划任务中的“分”字段必须有数值,绝对不能为空或是*号,而“日”和“星期”字段不能同时使用,否则就会发生冲突。

最后再啰嗦一句,想必读者也已经发现了,诸如crond在内的很多服务默认调用的是Vim编辑器,相信大家现在能进一步体会到在Linux系统中掌握Vim文本编辑器的好处了吧。所以请大家一定要在彻底掌握Vim编码器之后再学习下一章。

第五章  用户身份与文件权限

5.1  用户身份与能力

设计Linux系统的初衷之一就是为了满足多个用户同时工作的需求,因此Linux系统必须具备很好的安全性。第1章在安装RHEL 7操作系统时,特别要求设置root管理员密码,这个root管理员就是存在于所有类UNIX系统中的超级用户。它拥有最高的系统所有权,能够管理系统的各项功能,如添加/删除用户、启动/关闭服务进程、开启/禁用硬件设备等。虽然以root管理员的身份工作时不会受到系统的限制,但俗语讲“能力越大,责任就越大”,因此一旦使用这个高能的root管理员权限执行了错误的命令可能会直接毁掉整个系统。使用与否,确实需要好好权衡一下。

在学习时是否要使用root管理员权限来控制整个系统呢?面对这个问题,网络上有很多文章建议以普通用户的身份来操作—这是一个更安全也更“无责任”的回答。今天,刘遄老师就要冒天下之大不韪给出自己的心得—强烈推荐大家在学习时使用root管理员权限!

这种为root管理员正名的决绝态度在网络中应该还是很少见的,我之所以力荐root管理员权限,原因很简单。因为在Linux的学习过程中如果使用普通用户身份进行操作,则在配置服务之后出现错误时很难判断是系统自身的问题还是因为权限不足而导致的;这无疑会给大家的学习过程徒增坎坷。更何况我们的实验环境是使用VMware虚拟机软件搭建的,可以将安装好的系统设置为一次快照,这即便系统彻底崩溃了,您也可以在5秒钟的时间内快速还原出一台全新的系统,而不用担心数据丢失。

总之,刘遄老师在培训时都推荐每位学生使用root管理员权限来学习Linux系统,等到工作时再根据生产环境决定使用哪个用户权限;这些仅与选择相关,而非技术性问题。

另外,很多图书或培训机构的老师会讲到,Linux系统中的管理员就是root。这其实是错误的,Linux系统的管理员之所以是root,并不是因为它的名字叫root,而是因为该用户的身份号码即UIDUser IDentification)的数值为0。在Linux系统中,UID就相当于我们的身份证号码一样具有唯一性,因此可通过用户的UID值来判断用户身份。在RHEL 7系统中,用户身份有下面这些。

Ø   管理员UID为0:系统的管理员用户。

Ø   系统用户UID为1~999: Linux系统为了避免因某个服务程序出现漏洞而被黑客提权至整台服务器,默认服务程序会有独立的系统用户负责运行,进而有效控制被破坏范围。

Ø   普通用户UID从1000开始:是由管理员创建的用于日常工作的用户。

需要注意的是,UID是不能冲突的,而且管理员创建的普通用户的UID默认是从1000开始的(即使前面有闲置的号码)。

为了方便管理属于同一组的用户,Linux系统中还引入了用户组的概念。通过使用用户组号码(GIDGroup IDentification),我们可以把多个用户加入到同一个组中,从而方便为组中的用户统一规划权限或指定任务。假设有一个公司中有多个部门,每个部门中又有很多员工。如果只想让员工访问本部门内的资源,则可以针对部门而非具体的员工来设置权限。例如,可以通过对技术部门设置权限,使得只有技术部门的员工可以访问公司的数据库信息等。

另外,在Linux系统中创建每个用户时,将自动创建一个与其同名的基本用户组,而且这个基本用户组只有该用户一个人。如果该用户以后被归纳入其他用户组,则这个其他用户组称之为扩展用户组。一个用户只有一个基本用户组,但是可以有多个扩展用户组,从而满足日常的工作需要。

5.1.1  useradd命令

useradd命令用于创建新的用户,格式为“useradd [选项] 用户名”。

可以使用useradd命令创建用户账户。使用该命令创建用户账户时,默认的用户家目录会被存放在/home目录中,默认的Shell解释器为/bin/bash,而且默认会创建一个与该用户同名的基本用户组。这些默认设置可以根据表5-1中的useradd命令参数自行修改。

 

5-1                                         useradd命令中的用户参数以及作用

参数

作用

-d

指定用户的家目录(默认为/home/username

-e

账户的到期时间,格式为YYYY-MM-DD.

-u

指定该用户的默认UID

-g

指定一个初始的用户基本组(必须已存在)

-G

指定一个或多个扩展用户组

-N

不创建与用户同名的基本用户组

-s

指定该用户的默认Shell解释器

 

下面我们创建一个普通用户并指定家目录的路径、用户的UID以及Shell解释器。在下面的命令中,请注意/sbin/nologin,它是终端解释器中的一员,与Bash解释器有着天壤之别。一旦用户的解释器被设置为nologin,则代表该用户不能登录到系统中:

 

[root@linuxprobe ~]# useradd -d /home/linux -u 8888 -s /sbin/nologin linuxprobe

[root@linuxprobe ~]# id linuxprobe

uid=8888(linuxprobe) gid=8888(linuxprobe) groups=8888(linuxprobe)

 

5.1.2  groupadd命令

groupadd命令用于创建用户组,格式为“groupadd [选项] 群组名”。

为了能够更加高效地指派系统中各个用户的权限,在工作中常常会把几个用户加入到同一个组里面,这样便可以针对一类用户统一安排权限。创建用户组的步骤非常简单,例如使用如下命令创建一个用户组ronny

 

[root@linuxprobe ~]# groupadd ronny

 

5.1.3  usermod命令

usermod命令用于修改用户的属性,格式为“usermod [选项] 用户名”。

前文曾反复强调,Linux系统中的一切都是文件,因此在系统中创建用户也就是修改配置文件的过程。用户的信息保存在/etc/passwd文件中,可以直接用文本编辑器来修改其中的用户参数项目,也可以用usermod命令修改已经创建的用户信息,诸如用户的UID、基本/扩展用户组、默认终端等。usermod命令的参数以及作用如表5-2所示。

5-2                                              usermod命令中的参数及作用

参数

作用

-c

填写用户账户的备注信息

-d -m

参数-m与参数-d连用,可重新指定用户的家目录并自动把旧的数据转移过去

-e

账户的到期时间,格式为YYYY-MM-DD

-g

变更所属用户组

-G

变更扩展用户组

续表

参数

作用

-L

锁定用户禁止其登录系统

-U

解锁用户,允许其登录系统

-s

变更默认终端

-u

修改用户的UID

 

大家不要被这么多参数吓坏了。我们先来看一下账户linuxprobe的默认信息:

 

[root@linuxprobe ~]# id linuxprobe

uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe)

 

然后将用户linuxprobe加入到root用户组中,这样扩展组列表中则会出现root用户组的字样,而基本组不会受到影响:

 

[root@linuxprobe ~]# usermod -G root linuxprobe

[root@linuxprobe ~]# id linuxprobe

uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root)

 

再来试试用-u参数修改linuxprobe用户的UID号码值。除此之外,我们还可以用-g参数修改用户的基本组ID,用-G参数修改用户扩展组ID

 

[root@linuxprobe ~]# usermod -u 8888 linuxprobe

[root@linuxprobe ~]# id linuxprobe

uid=8888(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root)

 

5.1.4  passwd命令

passwd命令用于修改用户密码、过期时间、认证信息等,格式为“passwd [选项] [用户名]

普通用户只能使用passwd命令修改自身的系统密码,而root管理员则有权限修改其他所有人的密码。更酷的是,root管理员在Linux系统中修改自己或他人的密码时不需要验证旧密码,这一点特别方便。既然root管理员可以修改其他用户的密码,就表示完全拥有该用户的管理权限。passwd命令中可用的参数以及作用如表5-3所示。

5-3                                              passwd命令中的参数以及作用

参数

作用

-l

锁定用户,禁止其登录

-u

解除锁定,允许用户登录

--stdin

允许通过标准输入修改用户密码,如echo "NewPassWord" | passwd --stdin Username

-d

使该用户可用空密码登录系统

-e

强制用户在下次登录时修改密码

-S

显示用户的密码是否被锁定,以及密码所采用的加密算法名称

 

接下来刘遄老师将演示如何修改用户自己的密码,以及如何修改其他人的密码(修改他人密码时,需要具有root管理员权限):

 

[root@linuxprobe ~]# passwd

Changing password for user root.

New password: 此处输入密码值

Retype new password: 再次输入进行确认

passwd: all authentication tokens updated successfully.

[root@linuxprobe ~]# passwd linuxprobe

Changing password for user linuxprobe.

New password: 此处输入密码值

Retype new password: 再次输入进行确认

passwd: all authentication tokens updated successfully.

 

假设您有位同事正在度假,而且假期很长,那么可以使用passwd命令禁止该用户登录系统,等假期结束回归工作岗位时,再使用该命令允许用户登录系统,而不是将其删除。这样既保证了这段时间内系统的安全,也避免了频繁添加、删除用户带来的麻烦:

 

[root@linuxprobe ~]# passwd -l linuxprobe

Locking password for user linuxprobe.

passwd: Success

[root@linuxprobe ~]# passwd -S linuxprobe

linuxprobe LK 2017-12-26 0 99999 7 -1 (Password locked.)

[root@linuxprobe ~]# passwd -u linuxprobe

Unlocking password for user linuxprobe.

passwd: Success

[root@linuxprobe ~]# passwd -S linuxprobe

linuxprobe PS 2017-12-26 0 99999 7 -1 (Password set, SHA512 crypt.)

 

5.1.5  userdel命令

userdel命令用于删除用户,格式为“userdel [选项] 用户名”。

如果我们确认某位用户后续不再会登录到系统中,则可以通过userdel命令删除该用户的所有信息。在执行删除操作时,该用户的家目录默认会保留下来,此时可以使用-r参数将其删除。userdel命令的参数以及作用如表5-4所示。

5-4                                                userdel命令的参数以及作用

参数

作用

-f

强制删除用户

-r

同时删除用户及用户家目录

 

下面使用userdel命令将linuxprobe用户删除,其操作如下:

 

[root@linuxprobe ~]# id linuxprobe

uid=8888(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe),0(root)

[root@linuxprobe ~]# userdel -r linuxprobe

[root@linuxprobe ~]# id linuxprobe

id: linuxprobe: no such user

5.2  文件权限与归属

尽管在Linux系统中一切都是文件,但是每个文件的类型不尽相同,因此Linux系统使用了不同的字符来加以区分,常见的字符如下所示。

Ø   -:普通文件。

Ø   d:目录文件。

Ø   l:链接文件。

Ø   b:块设备文件。

Ø   c:字符设备文件。

Ø   p:管道文件。

Linux系统中,每个文件都有所属的所有者和所有组,并且规定了文件的所有者、所有组以及其他人对文件所拥有的可读(r)、可写(w)、可执行(x)等权限。对于一般文件来说,权限比较容易理解:“可读”表示能够读取文件的实际内容;“可写”表示能够编辑、新增、修改、删除文件的实际内容;“可执行”则表示能够运行一个脚本程序。但是,对于目录文件来说,理解其权限设置来就不那么容易了。很多资深Linux用户其实也没有真正搞明白。

刘遄老师在这里给大家详细讲解一下目录文件的权限设置。对目录文件来说,“可读”表示能够读取目录内的文件列表;“可写”表示能够在目录内新增、删除、重命名文件;而“可执行”则表示能够进入该目录。

文件的读、写、执行权限可以简写为rwx,亦可分别用数字421来表示,文件所有者,所属组及其他用户权限之间无关联,如表5-5所示。

5-5                                                 文件权限的字符与数字表示

权限分配

文件所有者

文件所属组

其他用户

权限项

执行

执行

执行

字符表示

r

w

x

r

w

x

r

w

x

数字表示

4

2

1

4

2

1

4

2

1

文件权限的数字法表示基于字符表示(rwx)的权限计算而来,其目的是简化权限的表示。例如,若某个文件的权限为7则代表可读、可写、可执行(4+2+1);若权限为6则代表可读、可写(4+2)。我们来看这样一个例子。现在有这样一个文件,其所有者拥有可读、可写、可执行的权限,其文件所属组拥有可读、可写的权限;而且其他人只有可读的权限。那么,这个文件的权限就是rwxrw-r--,数字法表示即为764。不过大家千万别再将这三个数字相加,计算出7+6+4=17的结果,这是小学的数学加减法,不是Linux系统的权限数字表示法,三者之间没有互通关系。

Linux系统的文件权限相当复杂,但是用途很广泛,建议大家把它彻底搞清楚之后再学习下一节的内容。现在来练习一下。请各位读者分别计算数字表示法764642153731所对应的字符表示法,然后再把rwxrw-r--rw--w--wxrw-r--r--转换成数字表示法。

下面我们利用上文讲解的知识,一起分析图5-1中所示的文件信息。

5-1  通过ls命令查看到的文件属性信息

在图5-1中,包含了文件的类型、访问权限、所有者(属主)、所属组(属组)、占用的磁盘大小、修改时间和文件名称等信息。通过分析可知,该文件的类型为普通文件,所有者权限为可读、可写(rw-),所属组权限为可读(r--),除此以外的其他人也只有可读权限(r--),文件的磁盘占用大小是34298字节,最近一次的修改时间为42日的凌晨23分,文件的名称为install.log


695856371Web网页设计师②群 | 喜欢本站的朋友可以收藏本站,或者加入我们大家一起来交流技术!

0条评论

Loading...


发表评论

电子邮件地址不会被公开。 必填项已用*标注

自定义皮肤 主体内容背景
打开支付宝扫码付款购买视频教程
遇到问题联系客服QQ:419400980
注册梁钟霖个人博客