Linux学习 实操篇

5 组管理和权限管理

(1) 所有者

<1> 查看文件的所有者 [ls –ahl]
//谁创建了该文件,就自然的成为该文件的所有者。
<2> 修改文件所有者 [chown 用户名 文件名](change owner)
  -R:如果是目录,则使其下所有子文件或目录递归生效
改变所有者和所在组 [chown 用户名:组名]

(2) 用户组

<1> 组概述
<1.1> 在 linux 中的每个用户必须属于一个组,不能独立于组外。
<1.2> 谁创建了该文件,就自然的成为该文件的所有者。
<1.3> 这个文件的所在组就是该用户所在的组(默认)。
<1.4> 除文件的所有者和所在组的用户外,系统的其它用户都是文件的其它组。
<2> 新增组 [groupadd 组名]
<3> 删除组 [groupdel 组名]
<4> 查询用户所在组 [id 用户名]
<5> 增加用户时直接加上组 [useradd –g 用户组 用户]
//新建用户时不加组,默认新建一个与用户名相同的组,并加入用户。
<6> 修改已有用户的组 [usermod –g 用户组 用户名]
<7> 改变该用户登陆的初始目录 [usermod –d 目录名 用户名]
//用户需要有进入到新目录的权限。
<8> 查看文件/目录所在组 [ls –ahl]
<9> 修改文件/目录所在的组 [chgrp 组名 文件名](change group)
  -R:如果是目录,则使其下所有子文件或目录递归生效

(3) 权限

<1> 权限概述
<1.1> 第 0 位确定文件类型(d,-,l,c,b)
  -:普通文件
  l(link):链接,相当于 windows 的快捷方式
  d(directory):目录,相当于 windows 的文件夹
  c(character device):字符设备文件,鼠标,键盘
  b(block device):块设备,比如硬盘
  //r:read,w:write,e:execute
<1.2> 第 1-3 位确定所有者(该文件的所有者)拥有该文件的权限。---User
<1.3> 第 4-6 位确定所属组(同用户组的)拥有该文件的权限,---Group
<1.4> 第 7-9 位确定其他用户拥有该文件的权限 ---Other
<2> rwx权限详解
//可用数字表示为: r=4,w=2,x=1 因此 rwx=4+2+1=7 , 数字可以进行组合,比如777。
<2.1> rwx作用到文件
  [r]代表可读(read):可以读取,查看。
  [w]代表可写(write):可以修改,但是不代表可以删除该文件,删除一个文件的前提条件是对该文件所在的目录有写权限,才能删除该文件。
  [x]代表可执行(execute):可以被执行。
<2.2> rwx作用到目录
//如果要对目录内的文件进行操作,不止需要对文件的权限,也需要要有对该目录的相应权限。
  [r]代表可读(read):可以读取,ls查看目录内容。
  [w]代表可写(write):可以修改,对目录内创建+删除+重命名目录。
  [x]代表可执行(execute):可以进入该目录。
<3> 修改文件或者目录的权限
<3.1> +、-、=变更权限
为文件设置权限 [chmod u=rwx,g=rx,o=rx 文件名或目录](change mod)
//u(user):所有者  g(group):所在组  o(others):其他组  a(all):所有人,即所有者、所在组、其他组。
给文件去除或增加权限 [chmod u-x,g-x 文件名或目录]
<3.2> 通过数字变更权限 [chmod 777 文件名或目录]
//r=4 w=2 x=1,为每个角色设置权限时,只需将权限相加即可。

 

6 定时任务调度

(1) crond任务调度

<1> 概述
crond任务调度:是指系统通过crond程序在某个时间执行的特定的命令或程序。
//每隔一个时间段执行一次任务。
<2> 基本语法
<2.1> 进行定时任务的设置 [crontab 选项]
  -e:编辑crontab定时任务
  -l:查询crontab任务
  -r:删除当前用户所有的crontab任务
<2.2> 重启任务调度:[service crond restart]
<3> 快速入门
<3.1> 设置个人任务调度,执行 [crontab –e]
<3.2> 输入任务到调度文件,格式为 [*/1 * * * * 命令]
<3.3> 参数细节说明
  第一个*:一小时当中的第几分钟,范围为0-59。
  第二个*:一天当中的第几小时,范围为0-23。
  第三个*:一个月当中的第几天,范围为1-31。
  第四个*:一年当中的第几月,范围为1-12。
  第五个*:一周当中的星期几,范围为0-7(0和7都代表星期日)。
  //星期几和几号最好不要同时出现,因为他们定义的都是天。非常容易让管理员混乱。
<3.4> 特殊符号的说明
  *:代表任何时间。//比如第一个“*”就代表一小时中每分钟都执行一次的意思。
  ,:代表不连续的时间。//比如“0 8,12,16 * * *”,就代表在每天的8点0分,12点0分,16点0分都执行一次命令。
  -:代表连续的时间范围。//比如“0 5 * * 1-6 ”,代表在周一到周六的凌晨5点0分执行命令。
  */n:代表每隔多久执行一次。//比如“* */10 * * *,代表每隔10小时就执行一遍命令。
<4> 多条命令使用shell脚本
<4.1> 新建脚本 [vim /home/my.sh],写入命令。
<4.2> 给my.sh增加执行权限,[chmod u+x /home/my.sh]
<4.3> crontab -e,写入 [*/1 * * * * /home/my.sh]

(2) at定时任务

<1> 概述
<1.1> at命令是一次性定时计划任务,at的守护进程 atd会以后台模式运行,检查作业队列来运行。
<1.2> 默认情况下,atd守护进程每60秒检查作业队列,有作业时,会检查作业运行时间,如果时间与当前时间匹配,则运行此作业。
<1.3> at命令是一次性定时计划任务,执行完一个任务后不再执行此任务了。
<1.4> 在使用at命令的时候,一定要保证atd进程的启动,可以使用相关指令来查看 [ps -ef | grep atd]//可以检测 atd 是否在运行
<2> 基本语法
<2.1> [at 时间 日期][at 选项]
//按[enter]后即可输入指令或shell脚本路径。注意要有执行权限。删除错误字符[ctrl+Backspace]
  -m:当指定的任务被完成后,将给用户发送邮件,即使没有标准输出
  -l:展示当前所有at定时任务,[atq]的别名
  -d:删除当前所有at定时任务,[atrm]的别名
  //[atrm 编号]将job队列特定编号的job删除。
  -v:显示任务将被执行的时间
  -c:打印任务的内容到标准输出
  -V:显示版本信息
<2.2> 输出两次[Ctrl+D]结束at命令的输入。
<3> at时间定义
<3.1> 格式 [时间 日期]
<3.2> 指定时间
  ① 当前时间 [now]
  ② 指定具体的时间 [hh:mm](小时:分钟)
  //假如该时间已过去,那么就放在第二天执行。 例如:04:00
  ③ 使用模糊的词语来指定时间 [midnight](深夜),[noon](中午),[teatime](饮茶时间,一般是下午4点)
  ④ 使用12小时计时制指定时间,即在时间后面加上 [AM](上午)、[PM](下午)来说明是上午还是下午。
  //例如:12pm
<3.3> 指定日期
//指定日期必须跟在指定时间后面。例如:04:00 12/24/2020
  ① 使用绝对计时法 [month day](月 日)、 [mm/dd/yy](月/日/年)、[dd.mm.yy](日.月.年)
  ② 使用相对计时法 [+ count time-units]
  //count是时间的数量,几天,几小时。time-units是时间单位,这里能够是 [minutes](分钟)、[hours](小时)、[days](天)、[weeks](星期)。 例如:[now + 5 minutes]
  ③ 直接使用 [today](今天)、[tomorrow](明天)来指定完成命令的时间。

 

7 Linux磁盘分区、挂载

(1) Linux 分区

<1> 挂载:将一个分区和一个目录联系起来。访问目录,实际上是访问分区。
<2> 硬盘说明
<2.1> Linux硬盘分IDE硬盘和SCSI硬盘,目前基本上是SCSI硬盘。
<2.2> IDE硬盘标识符为"hdx~"
    "hd"表示分区所在设备的类型,即IDE硬盘。
    "x"为盘号(a为基本盘,b为基本从属盘,c为辅助主盘,d为辅助从属盘)。
    "~"代表分区,前四个分区用数字 1 到 4 表示,它们是主分区或扩展分区,从 5 开始就是逻辑分区。
    //比如:hdb2表示为第二个 IDE 硬盘上的第二个主分区或扩展分区。
<2.3> SCSI硬盘标识符为"sdx~"
    "sd"来表示分区所在设备的类型,即SCSI硬盘。
    //其余则和 IDE 硬盘的表示方法一样。
<3> 查看所有设备挂载情况 [lsblk](list block)
    -f:输出文件系统的详细信息

(2) 如何增加一块硬盘

<1> 使用VMware WorkStation为虚拟机添加硬盘,添加之后 [reboot]。
<2> 分区 [fdisk 设备名称]
//比如:[fdisk /dev/sdb]
    p:显示磁盘分区,同 [fdisk –l]
    n:新增分区
    d:删除分区
    m:显示命令列表
    w:写入并退出
    q:退出但不保存
    //开始分区后输入n,代表新增分区,然后选择p,代表分区类型为主分区。enter默认使用2048扇区,输入+size{K,M,G}为分区分配大小。最后输入w写入分区并退出,若不保存退出输入q
<3> 格式化磁盘 [mkfs -t ext4 设备名称](make file system)
//其中ext4是分区类型。
<4> 挂载 [mount 设备名称 挂载目录]
//用命令行挂载,重启后会失效。
卸载 [umount 设备名称/挂载目录]
<5> 编辑fstab可以可以自动挂载 [vim /etc/fstab]
拷贝一条并修改添加 [UUID/设备名称 挂载目录  ext4 default 0/1 0/1/2]
//比如 [/dev/sdb1 /opt/newdir  ext4 default 0 0]
//既可以使用UUID也可以使用设备名称;末尾两个数字,第一个代表是否做挂载点内备份,第二个,数字0代表不检查磁盘扇区,1代表其他目录文件检查,2代表根目录文件检查。
添加完成后,执行 [mount -a] 即刻生效,[reboot]也有相似效果。

(3) 磁盘情况查询

<1> 查询系统整体磁盘使用情况 [df -h](disk free)
<2> 查询指定目录的磁盘占用情况 [du -h 目录](disk usage)
//若不指定目录则为当前目录。
//例:[du -hac --max-depth=1 /opt]
    -s:指定目录占用大小汇总
    -h:带计量单位
    -a:含文件
    -c:列出明细的同时,增加汇总值
    --max-depth=1:子目录深度

(4) 实用指令

<1> 统计/opt 文件夹下文件的个数。 [ls -l /opt | grep "^-" | wc -l]
//展示所有文件,过滤以-开头的文件,并显示数量。
<2> 统计/opt 文件夹下目录的个数。 [ls -l /opt | grep "^d" | wc -l]
//展示所有文件,过滤以^开头的文件,并显示数量。
<3> 统计/opt 文件夹下文件的个数,包括子文件夹文件。 [ls -lR /opt | grep "^-" | wc -l]
//递归展示所有文件,过滤以-开头的文件并显示数量。
<4> 统计/opt 文件夹下目录的个数,包括子文件夹文件。 [ls -lR /opt | grep "^d" | wc -l]
//递归展示所有文件,过滤以^开头的文件,并显示数量。 
<5> 以树状显示目录结构 [tree 目录]
//如果没有tree命令,则使用[yum install tree]安装

 

8 网络配置

(1) NAT网络配置原理

虚拟机有一个ip地址,主机为虚拟机生成了一个虚拟网卡VMnet8,虚拟机通过虚拟网卡与主机通信(二者ip地址在同一网段),再由主机通过无线网卡或者WLAN与外界通信。

(2) 查看网络IP和网关

<1> 查看虚拟网络编辑器和修改 IP 地址
    VMware WorkStation->编辑->虚拟网络编辑器
<2> 查看网关
    VMware WorkStation->编辑->虚拟网络编辑器->NAT设置

(3) 常用命令

<1> 查看windows环境的中VMnet8网络配置 [ipconfig]
<2> 查看linux的网络配置 [ifconfig]
<3> 测试主机之间网络连通性 [ping 目的主机]

(4) linux网络环境配置

//两者修改的时虚拟机的ip地址,设置指定ip后,还需修改虚拟网卡ip。
<1> 自动获取
//登陆后,通过界面的来设置自动获取ip,特点:linux启动后会自动获取iP,缺点是每次自动获取的ip地址可能不一样。
    虚拟机->应用工具->系统工具->设置->网络->有线连接->IPv4->自动
<2> 指定ip
//直接修改配置文件来指定iP,并可以连接到外网。
<2.1> 修改配置文件 [vim /etc/sysconfig/network-scripts/ifcfg-ens33]//修改虚拟机的ip地址
//将ip地址配置的静态的,比如:ip地址为192.168.200.130
<2.2> ifcfg-ens33 文件说明

#接口名(设备,网卡)
DEVICE=eth0
#MAC 地址
HWADDR=00:0C:2x:6x:0x:xx
#网络类型(通常是 Ethemet)
TYPE=Ethernet
#随机 id
UUID=926a57ba-92c6-4231-bacb-f27e5e6a9f44
#系统启动的时候网络接口是否有效(yes/no)
ONBOOT=yes

以下为需要修改的内容:

# IP 的配置方法[none|static|bootp|dhcp](引导时不使用协议|静态分配IP|BOOTP协议|DHCP协议)
BOOTPROTO=static
#IP 地址
IPADDR=192.168.100.120
#网关
GATEWAY=192.168.100.2
#域名解析器
DNS1=192.168.100.2

<2.3> 重启网络服务或者重启系统生效 [service network restart]、[reboot]
<2.4> VMware WorkStation->编辑->虚拟网络编辑器
    修改虚拟网卡ip和网关//以上修改的是虚拟机ip,必须保证虚拟机ip与虚拟网卡ip在同一网段,否则不能通信。

(5) 设置主机名和hosts映射

<1> 设置主机名
    查看主机名 [hostname]
    修改主机名 [vim /etc/hostname]
    修改后,重启生效 [reboot]
<2> 设置hosts映射
//在系统的配置文件中保存了映射关系,使用时主机名时,自动在配置文件中检索映射关系,将主机名转换为ip地址,本质仍是ip地址,相当于给ip地址起了别名。
<2.1> windows设置hosts映射
    在C:\Windows\System32\drivers\etc\hosts文件指定即可。
    //修改系统文件必须先给定修改权限。
    //案例: [192.168.100.120 hspedu100]
<2.2> linux设置hosts映射
    在/etc/hosts文件指定 [vim /etc/hosts]
    //案例: [192.168.100.1 ThinkPad-PC]
    //主机名随意

(6) 主机名解析过程分析

<1> Hosts
    一个文本文件,用来记录IP和Hostname(主机名)的映射关系。
<2> DNS
    DNS,就是Domain Name System的缩写,翻译过来就是域名系统是互联网上作为域名和IP地址相互映射的一个分布式数据库。
<3> 解析过程
<3.1> 浏览器先检查浏览器缓存中有没有该域名解析IP地址,有就先调用这个IP完成解析;
<3.2> 如果没有,就检查DNS解析器缓存,如果有直接返回IP完成解析。这两个缓存,可以理解为本地解析器缓存。
    //windows cmd窗口输入
    DNS域名解析缓存 [ipconfig /displaydns]
    手动清理dns缓存 [ipconfig /flushdns]
<3.3> 如果本地解析器缓存没有找到对应映射,检查系统中hosts文件中有没有配置对应的域名IP映射,如果有,则完成解析并返回。
<3.4> 如果 本地 DNS 解析器缓存 和 hosts 文件 中均没有找到对应的 IP,则到域名服务 DNS 进行解析域。

 

9 进程管理

(1) 显示系统执行的进程 

<1> 显示当前执行的进程 [ps 选项]
//可以不加任何参数和选项
    -a:显示当前终端的所有进程信息
    -u:以用户的格式显示进程信息
    -x:显示后台进程运行的参数
    -e:显示所有进程
    -f:全格式
<2> 查看是否存在某个进程 [ps –aux | grep 进程名/进程号]
    USER:用户名称
    PID:进程号
    %CPU:进程占用 CPU 的百分比
    %MEM:进程占用物理内存的百分比
    VSZ:进程占用的虚拟内存大小(单位:KB)
    RSS:进程占用的物理内存大小(单位:KB)
    TT:终端名称,缩写
    STAT:进程状态,其中S-睡眠,s-表示该进程是会话的先导进程,N-表示进程拥有比普通优先级更低的优先级,R-正在运行,D-短期等待,Z-僵死进程,T-被跟踪或者被停止等等。
    STARTED:进程的启动时间
    TIME:CPU 时间,即进程使用 CPU 的总时间
    COMMAND:启动进程所用的命令和参数,如果过长会被截断显示
<3> 以全格式显示当前所有的进程 [ps -ef]
//ps -efps -aux,这两者的输出结果差别不大,但展示风格不同。aux是BSD风格,而-ef是System V风格。
    UID:用户 ID
    PID:进程 ID
    PPID:父进程 ID
    C:CPU 用于计算执行优先级的因子。数值越大,表明进程是 CPU 密集型运算,执行优先级会降低;数值越小,表明进程是 I/O 密集型运算,执行优先级会提高
    STIME:进程启动的时间
    TTY:完整的终端名称
    TIME:CPU 时间
    CMD:启动进程所用的命令和参数

(2) 终止进程kill和killall

//终止父进程,子进程不会  会被终止。
<1> 通过进程号终止进程:[kill 选项 进程号]
    -9:表示强制进程立即停止
<2> 通过进程名称杀死进程,也支持通配符 [killall 选项 进程名]
    -9:表示强制进程立即停止
<3> 实用指令
禁止某个非法登录用户 [kill 进程号]
终止远程登录服务sshd [kill sshd的进程号]
重启sshd服务 [systemctl start sshd.service]、[/bin/systemctl start sshd.service]
终止多个gedit [killall gedit]
强制终止一个终端 [kill -9 bash的进程号]
//因为bash此时正在执行,系统会认为用户误操作导致关闭,因此-9强制终止。

(3) 查看进程树

显示进程树 [pstree 选项]
    -p:显示进程的PID
    -u:显示进程的所属用户

(4) 服务(service)管理

<1> 概述
//服务本质上也是一个进程。
服务(service)本质就是进程,但是是运行在后台的,通常都会监听某个端口,等待其它程序的请求,比如mysql、sshd、防火墙等,因此我们又称为守护进程。
如果防火墙打开,防火墙会将端口与程序分隔开,每个程序的请求都必须经过防火墙,防火墙若设置打开,那么该程序就可以访问服务;防火墙若设置该端口关闭,那么该程序就无法访问到服务。
<2> service管理指令
查看service指令管理的服务 [ls -l /etc/init.d/] 或 [setup]->系统服务
//关闭和打开只是临时生效,重启后仍会恢复原状。
开启服务、终止服务、重启服务、重新加载服务、查询服务状态 [service 服务名/服务名.service start/stop/restart/reload/status]
//既可以使用服务名,也可以使用服务名.service,如:network或者network.service。关闭network,shhd也不能使用。
//在 CentOS7.0 后 很多服务不再使用 service ,而是 systemctl。
<3> 运行级别
<3.1> Linux系统有7种运行级别(runlevel)
//常用的是级别3和5。
运行级别0:系统停机状态,系统默认运行级别不能设为 0,否则不能正常启动。
运行级别1:单用户工作状态,root 权限,用于系统维护,禁止远程登陆。
运行级别2:多用户状态(没有NFS),不支持网络。
运行级别3:完全的多用户状态(有NFS),无界面,登陆后进入控制台命令行模式。
运行级别4:系统未使用,保留。
运行级别5:X11 控制台,登陆后进入图形 GUI 模式。
运行级别6:系统正常关闭并重启,默认运行级别不能设为 6,否则不能正常启动。
<3.2> 开机的流程说明
开机->BIOS->/boot->systemd进程1->运行级别->运行级别对应的服务
<3.3> CentOS7后运行级别说明
查看当前默认运行级别 [systemctl get-default]
设置默认运行级别 [systemctl set-default 运行级别.target]
//multi-user.target: 代指运行级别3
//graphical.target: 代指运行级别5
<4> chkconfig管理指令
查看chkconfig指令管理的服务 [chkconfig --list | grep 服务名](check config) 或 [ls -l /etc/init.d/]
//某个服务自启动或关闭永久生效。
设置服务在某运行级别自动启动或关闭 [chkconfig --level 级别数 服务名 on/off]
chkconfig重新设置服务后自启动或关闭,需要重启机器[reboot]生效。
//Centos7.0 后,很多服务使用systemctl管理。
<5> systemctl管理指令
//systemctl是srvice和chkconfig的结合体,既能暂时管理状态又可以永久管理状态。
查看systemctl指令管理的服务 [ls -l /usr/lib/systemd/system/]
//关闭和打开只是临时生效,重启后仍会恢复原状。
开启服务、终止服务、重启服务、重新加载服务、查询服务状态 [systemctl start/stop/restart/status 服务名]
查看服务开机启动状态, grep可以进行过滤 [systemctl list-unit-files | grep 服务名]
//某个服务自启动或关闭永久生效。
设置服务开机启动 [systemctl enable 服务名]
关闭服务开机启动 [systemctl disable 服务名]
查询某个服务是否是自启动 [systemctl is-enabled 服务名]
<6> 打开或者关闭防火墙指定端口
打开端口:[firewall-cmd --permanent --add-port=端口号/协议]
//查看端口协议 [netstat -anp | grep 服务名](network status)
关闭端口:[firewall-cmd --permanent --remove-port=端口号/协议]
打开或关闭端口需要重新载入,才能生效:[firewall-cmd --reload]
查询端口是否开放:[firewall-cmd --query-port=端口/协议]

(4) 动态监控进程

<1> 概述
top与ps命令很相似。它们都用来显示正在执行的进程。top 与 ps 最大的不同之处,在于 top 在执行一段时间可以更新正在运行的的进程。
<2> 动态显示正在执行的程序 [top 选项]
<2.1> 选项
    -d:秒数 指定top命令每隔几秒更新。若不写秒数默认是3秒
    -i:使top不显示任何闲置或者死进程
    -p:通过指定监控进程ID来仅仅监控某个进程的状态。
<2.2> 交互操作
    P:以CPU使用率排序,默认就是此项
    M:以内存的使用率排序
    N:以PID排序
    q:退出tp
    u->用户名:监视特定用户
    k->进程号:终止指定的进程

(5) 监控网络状态

//显示端口的连接(estabished)信息和监听(listen)信息。
<1> 查看系统网络情况 [netstat 选项]
    -an:按一定顺序排列输出
    -p:显示被调用的进程
<2> 请查看某服务的服务的信息 [netstat 选项 | grep 服务名]

 

10 RPM与YUM

(1) rpm包的管理

<1> 概述
rpm用于互联网下载包的打包及安装工具,它包含在某些Linux分发版中。它生成具有.RPM扩展名的文件。
RPM是RedHat Package Manager(RedHat 软件包管理工具)的缩写,类似 windows的setup.exe,这一文件格式名称虽然打上了RedHat的标志,但理念是通用的。
<2> 基本格式
包名:firefox-60.2.2-1.el7.centos.x86_64
名称:firefox
版本号:60.2.2-1
适用操作系统: el7.centos.x86_64
表示 centos7.x 的 64 位系统
//如果是 i686、i386 表示 32 位系统,noarch 表示通用
<3> 查询指令
查询已安装的rpm列表 [rpm –qa | grep 包名]
    q(query):查询
    a(all):所有
    l:显示rpm中的文件
查询所安装的所有rpm软件包 [rpm -qa | more]
查询软件包是否安装 [rpm -q 包名]
查询软件包信息 [rpm -qi 包名]
查询软件包中的文件 [rpm -ql 包名]
查询文件所属的软件包 [rpm -qf 文件路径]
<4> 安装指令 [rpm -ivh 包路径]
    i(install):安装rpm包
    v(verbose):显示提示
    h(hash):显示进度条
<5> 卸载指令 [rpm -e 包名](erase)
<5.1> 如果其它软件包依赖于您要卸载的软件包,卸载时则会产生错误信息。
removing these packages would break dependencies:XXX is needed by XXX
<5.2> 如果我们就是要删除这个rpm包,可以增加参数 --nodeps ,就可以强制删除,但是一般不推荐这样做,因为依赖于该软件包的程序可能无法运行。
强制卸载 [rpm -e --nodeps 包名]
    e:卸载

(2) yum指令

<1> 概述
//类似maven仓库。
Yum是一个Shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包。
<2> 查询yum服务器是否有需要安装的软件 [yum list | grep 软件名]
<3> 安装指定的yum包 [yum install 软件名]

posted @ 2023-04-01 17:21  10kcheung  阅读(82)  评论(0)    收藏  举报