10 组管理和权限管理10.1 Linux组的基本介绍10.2 文件/目录的所有者10.3 文件/目录的所在组10.4 权限的基本介绍10.5 rwx权限详解10.6 修改权限指令-chmod10.7 修改文件所有者-chown10.8 修改文件所在组-chgrp10.9 最佳实践-警察和土匪游戏11 定时任务调度11.1 crond任务调度12 linux磁盘分区、挂载12.1 分区的基本知识12.2 Linux分区12.3 挂载的经典案例12.4 查询系统整体磁盘使用情况12.5 查询指定目录的磁盘占用情况12.6 磁盘情况-工作中实用指令13 linux的网络配置13.1 linux的网络配置的原理图13.2 查看网络IP和网关13.3 linux网络环境配置13.2.1 第一种方法:自动获取ip地址13.3.2 第二种方法:配置固定的ip地址13.4 修改主机名14 进程管理(重点)14.1 基本介绍14.1.1 显示系统执行的进程14.1.2 ps指令详解14.2 终止进程kill和killall14.3 查看进程树pstree14.4 服务(service)管理14.4.1 查看服务名称14.4.2 服务的运行级别(runlevel)14.5 chkconfig指令14.5 动态监控进程14.6 监控网络状态15 软件包管理15.1 rpm包的管理15.2 卸载rpm包15.3 安装rpm包15.4 yum包的管理16 大厂面试题16.1 百度面试题16.2 瓜子二手车面试题17 感悟分享18 资料附录
10 组管理和权限管理
10.1 Linux组的基本介绍
在linux中的每个用户必须属于一个组,不能独立于组外。在linux中每个文件有所有者、所在组、其它组的概念。
1) 所有者
2) 所在组
3) 其它组
4) 改变用户所在的组
示意图如下:
10.2 文件/目录的所有者
- 一般为文件的创建者,谁创建了该文件,就自然的成为该文件的所有者。
- 查看文件的所有者
指令:ls –ahl
应用实例:创建一个组police,再创建一个用户tom,将tom放在police组,然后使用tom来创建一个文件ok.txt。【参考补充示例】- 修改文件的所有者
指令:chown 用户名 文件名
应用案例:使用root用户创建一个文件apple.txt,然后将该文件的所有者修改成tom。
补充示例:
示例:增加用户时直接指定用户的家目录和用户组
创建一个用户,名字叫abc,主目录是/home/abc/目录,属于aabb这个组。useradd -d /home/abc/ abc -m -g aabb
-d的意思是指定用户的主目录 -m的意思是,如果主目录不存在,那么就自动创建这个目录 -g的意思是指定该用户属于哪个组
注意1:我们需要先创建组aabb。命令:groupadd aabb注意2:我们新增用户后,要及时通过root用户设置新增用户的密码。这是一个好习惯!
10.3 文件/目录的所在组
- 当某个用户创建了一个文件后,默认情况下,这个文件的所在组就是该用户所在的组。
- 查看文件/目录所在组
指令:ls –ahl
应用实例:同上。- 修改文件所在的组
指令:chgrp 组名 文件名
应用实例:使用root用户创建文件orange.txt,看看当前这个文件属于哪个组【root】,然后将这个文件所在组,修改到police组。- 其他组
除文件的所有者和所在组的用户外,系统的其它用户都是文件的其它组。- 改变用户所在组
在添加用户时,可以指定将该用户添加到哪个组中,同样的用root的管理权限可以改变某个用户所在的组。【参考补充示例】
指令:
1) usermod –g 组名 用户名
2) usermod –d 目录名 用户名 (功能描述:改变该用户登陆的初始目录)
应用实例:创建一个土匪组(bandit)将tom这个用户从原来所在的police组,修改到bandit(土匪)组,命令usermod -g bandit tom
10.4 权限的基本介绍
10.5 rwx权限详解
rwx权限详解
文件及目录权限实际案例
10.6 修改权限指令-chmod
第一种方式:+ 、-、= 变更权限
演示案例如下截图:
第二种方式:通过数字变更权限
10.7 修改文件所有者-chown
10.8 修改文件所在组-chgrp
10.9 最佳实践-警察和土匪游戏
(1)创建组
(2)创建用户(好习惯,创建用户后要设置密码)
(3)jack 创建一个文件,自己可以读写,本组人可以读,其它组没人任何权限
(4)jack 可以修改该文件,本组人可以读写,让其它组人可以读
(5)xh 投靠警察,看看是否可以读写(使用root用户)
11 定时任务调度
11.1 crond任务调度
- 说明:
crontab 进行定时任务的设置。- 概述:
任务调度:是指系统在某个时间执行的特定的命令或程序。
任务调度分类:
- 1) 系统工作:有些重要的工作必须周而复始地执行。如病毒扫描等。
- 2) 个别用户工作:个别用户可能希望执行某些程序。比如对mysql数据库的备份。
- 基本语法:
crontab [选项]- 常用选项
- 快速入门:
设置任务调度文件:/etc/crontab
设置个人任务调度。执行crontab –e
命令。
接着输入任务到调度文件,如:*/1 * * * * ls –l /etc/ > /tmp/to.txt
意思说:每小时的每分钟执行ls –l /etc/ > /tmp/to.txt
命令- 参数细节说明:
5个占位符的说明:
特殊符号的说明:
特定时间执行任务案例:- 应用实例:
案例1:每隔1分钟,就将当前的日期信息,追加到/tmp/mydate.log 文件中
步骤:
1) 编写一个文件/home/mytask1.sh
,文件内容是:date >> /tmp/mydate.log
2) 给文件/home/mytask1.sh
一个可以执行的权限,命令chmod 744 /home/mytask1.sh
3) 设置个人任务调度。执行crontab –e
命令
4) 输入任务到调度文件,任务内容:*/1 * * * * /home/mytask1.sh
5) 查看文件/tmp/mydate.log,成功!
案例2:每隔1分钟,将当前日期和日历信息,都追加到/tmp/mycal.log 文件中
步骤:
1) 编写一个文件/home/mytask2.sh
,文件内容是:date >> /tmp/mycal.log
和cal >> /tmp/mycal.log
2) 给文件/home/mytask2.sh
一个可以执行的权限,命令chmod 744 /home/mytask2.sh
3) 设置个人任务调度。执行crontab –e
命令
4) 输入任务到调度文件,任务内容:*/1 * * * * /home/mytask2.sh
5) 查看文件/tmp/mycal.log,成功!
截图同上!不在赘图!
案例3:每天凌晨2:00将mysql数据库testdb,备份到文件/tmp/mydb.bak中。
步骤:
1) 编写一个文件/home/mytask3.sh
,文件内容是:/usr/local/mysql/bin/mysqldump -uroot -proot testdb > /tmp/mydb.bak
2) 给文件/home/mytask3.sh
一个可以执行的权限,命令chmod 744 /home/mytask3.sh
3) 设置个人任务调度。执行crontab –e
命令
4) 输入任务到调度文件,任务内容:0 2 * * * /home/mytask3.sh
5) 查看文件/tmp/mydb.bak,成功!
截图同上!不在赘图!- crond 相关指令:
1) conrtab –r:终止任务调度(删除所有任务调度)。
2) crontab –l:列出当前有那些任务调度。
3) service crond restart [重启任务调度]- 拓展:比较难的shell脚本的编写
shell脚本文件内容:
#!/bin/bash #备份路径BACKUP=/data/backup/sql/dy#当前时间DATETIME=$(date +%Y-%m-%d_%H%M%S)echo "===备份开始==="echo "备份文件存放于${BACKUP}/$DATETIME.tar.gz"#数据库地址HOST=localhost#数据库用户名DB_USER=root#数据库密码DB_PW=Ces123456#创建备份目录[ ! -d "${BACKUP}/$DATETIME" ] && mkdir -p "${BACKUP}/$DATETIME"
#后台系统数据库DATABASE=dy_backgroundmsmysqldump -u${DB_USER} -p${DB_PW} --host=$HOST -q -R --databases $DATABASE | gzip > ${BACKUP}/$DATETIME/$DATABASE.sql.gz
#投入品监管数据库DATABASE=dy_firipmysqldump -u${DB_USER} -p${DB_PW} --host=$HOST -q -R --databases $DATABASE | gzip > ${BACKUP}/$DATETIME/$DATABASE.sql.gz
#压缩成tar.gz包cd $BACKUPtar -zcvf $DATETIME.tar.gz $DATETIME#删除备份目录rm -rf ${BACKUP}/$DATETIME
#删除30天前备份的数据find $BACKUP -mtime +30 -name "*.tar.gz" -exec rm -rf {} \;echo "===备份成功==="
注:find:linux的查找命令,用户查找指定条件的文件。-mtime:标准语句写法。+10:查找10天前的文件,这里用数字代表天数,+30表示查找30天前的文件。"*.*":希望查找的数据类型,"*.jpg"表示查找扩展名为jpg的所有文件,"*"表示查找所有文件,这个可以灵活运用,举一反三-exec:固定写法。rm -rf:强制删除文件,包括目录。{} \; :固定写法,一对大括号+空格+\;
12 linux磁盘分区、挂载
12.1 分区的基本知识
分区的方式(知道即可):
Windows下的磁盘分区:
12.2 Linux分区
原理介绍:
Linux系统分区的原理示意图:
硬盘说明:
查看所有设备(光驱/media,u盘,硬盘)挂载情况
命令:lsblk 或者 lsblk -f 【简记:老师不离开】
12.3 挂载的经典案例
- 说明:
下面我们以增加一块新的虚拟硬盘2G为例来熟悉下磁盘的相关指令和深入理解磁盘分区、挂载、卸载的概念。
图同上【Linux系统分区的原理示意图】。- 如何增加一块硬盘,步骤如下:
1) 虚拟机添加硬盘
2) 分区fdisk /dev/sdb
3) 格式化mkfs -t ext4 /dev/sdb1
4) 挂载mount /dev/sdb1 /home/newdisk/
卸载umount /dev/sdb1 或者 umount /home/newdisk/
5) 设置可以自动挂载vim /etc/fstab
,添加完成后,执行mount -a
即刻生效。- 步骤一:虚拟机添加硬盘
先选中一台虚拟机,然后右键该虚拟机,点击【设置】,然后在硬件列表里选中【硬盘(SCSI)】,点击【添加(A)】,然后一路【下一步】,中间只有【选择磁盘大小】的地方需要修改,直到完成。然后重启系统(才能识别)!
重新查看所有设备(光驱/media,u盘,硬盘)挂载情况- 步骤二:分区命令:
fdisk /dev/sdb
- 开始对/sdb分区:
- m 显示命令列表
- p 显示磁盘分区,同:fdisk -1
- n 新增分区
- d 删除分区
- w 写入并退出
- 说明:开始分区后输入n,新增分区,然后选择p,分区类型为主分区。主分区编号:输入1后回车,是否默认剩余全部空间,回车。最后输入w写入分区并退出,若不保存退出输入q。
- 步骤三:格式化磁盘
格式化命令:mkfs -t ext4 /dev/sdb1
其中ext4是格式化后的文件类型- 步骤四:挂载,先创建一个目录/home/newdisk/,然后将一个分区与一个目录联系起来,挂载命令:
mount 设备名称 挂载目录
注意:用命令行挂载重启后会失效!- 步骤五:永久挂载:通过修改/etc/fstab文件实现挂载,添加完成后,执行
mount -a
即刻生效。vim /etc/fstab
12.4 查询系统整体磁盘使用情况
- 基本语法:
df -h- 应用实例:
查询系统整体磁盘使用情况。
12.5 查询指定目录的磁盘占用情况
- 基本语法:
du -h /目录- 查询指定目录的磁盘占用情况,默认为当前目录
-s 指定目录占用大小汇总
-h 带计量单位
-a 含文件
--max-depth=1 子目录深度
-c 列出明细的同时,增加汇总值- 应用实例:
查询/usr/目录
的磁盘占用情况,深度为1
命令:du -ach --max-depth=1 /usr/
12.6 磁盘情况-工作中实用指令
- 1、统计/home/文件夹下文件的个数
ls –l /home/ | grep “^-” | wc -l
- 2、统计/home/文件夹下目录的个数
ls –l /home/ | grep “^d” | wc -l
- 3、统计/home/文件夹下文件的个数,包括子文件夹里的
ls –lR /home/ | grep “^-” | wc -l
- 4、统计/home/文件夹下目录的个数,包括子文件夹里的
ls –lR /home/ | grep “^d” | wc -l
- 5、以树状显示home目录结构
tree /home/
[没有tree指令咋办,使用yum来安装]
效果:
13 linux的网络配置
13.1 linux的网络配置的原理图
目前我们的网络配置采用的是NAT
13.2 查看网络IP和网关
查看VMware虚拟网络编辑器
修改VMnet8的ip地址
查看虚拟机的网关
查看windows环境的中VMnet8网络配置 (ipconfig指令方式和图形化界面方式)
ipconfig指令方式
图形化界面方式
使用ping,测试主机之间网络连通性
Linux ping Windows
Windows ping Linux
13.3 linux网络环境配置
13.2.1 第一种方法:自动获取ip地址
勾选【自动连接(A)】即可
说明
登陆后,通过界面来设置自动获取ip。
特点
1) 配置比较简单。
2) 每次启动linux后,分配的ip地址可能不一样。不适合做服务器。
13.3.2 第二种方法:配置固定的ip地址
- 方式一:
通过图像化界面进行操作,系统 -> 首选项 -> 网络连接 -> 选中【System eth0】-> 编辑
此种方式,不需要重启网路服务或者重启虚拟机,因为我们点击【应用】的本质就是重启网络服务! -
方式二:
直接修改配置文件来指定IP,并可以连接到外网(程序员推荐),
编辑vim /etc/sysconfig/network-scripts/ifcfg-eth0
(原装的虚拟机)
或者vim /etc/sysconfig/network-scripts/ifcfg-Auto_eth1
(复制的原装的虚拟机,本博主使用的)
要求:将ip地址配置为静态的static(或为none也行)
,ip地址为:192.168.xxx.xxx
如果希望配置生效:
法1) reboot // 重启系统
法2) service network restart // 重启网络服务
配置文件说明:
13.4 修改主机名
- 1) 查看当前主机名
hostname- 2) 修改linux的主机映射文件
vim /etc/sysconfig/network
文件中内容如下:
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME= hadoop // 写入新的主机名
注意:主机名称不要有“_”下划线,不识别。- 3) 修改
vim /etc/hosts
文件增加ip和主机的映射
192.168.25.204 hadoop
….- 4) 并重启设备,生效。
- 5) 如果希望Windows也可以通过
主机名
来连接CentOS,进入C:\Windows\System32\drivers\etc\hosts 192.168.25.104 hadoop
14 进程管理(重点)
14.1 基本介绍
- 在LINUX中,每个执行的程序(代码)都称为一个
进程
。每一个进程都分配一个ID号
。- 每一个进程,都会对应一个父进程,而这个父进程可以复制多个子进程。例如:www服务器。
- 每个进程都可能以两种方式存在的。
前台与后台
,所谓前台进程就是用户目前的屏幕上可以进行操作的。后台进程则是实际在操作,但由于屏幕上无法看到的进程,通常使用后台方式执行,例如:[sshd,crond]。- 一般系统的服务都是以后台进程的方式存在,而且都会常驻在系统中。直到关机才才结束。
14.1.1 显示系统执行的进程
- ps命令是用来查看目前系统中,有哪些正在执行,以及它们执行的状况。可以不加任何参数。
用法说明:- ps -aux // 显示所有的进程
- ps -aux | more // 分页显示所有的进程
- ps -aux | grep sshd // 查看sshd进程
14.1.2 ps指令详解
应用实例:以全格式显示当前所有的进程,查看进程的父进程。
演示截图:
查看sshd进程的父进程号是多少?
14.2 终止进程kill和killall
- 介绍:
若是某个进程执行一半需要停止时,或是已消了很大的系统资源时,此时可以考虑停止该进程。使用kill命令来完成此项任务。- 基本语法:
kill [选项] 进程号 (功能描述:通过进程号杀死进程,-9 强制终止)
killall 进程名称 (功能描述:通过进程名称杀死进程,也支持通配符,这在系统因负载过大而变得很慢时很有用)- 常用选项:
-9 : 表示强迫进程立即停止。- 最佳实践:
案例1:踢掉某个非法登录用户。
案例2:终止远程登录服务sshd,在适当时候再次重启sshd服务。
案例3:终止多个gedit编辑器。通过进程名称终止进程
killall gedit
案例4:强制杀掉一个终端。
kill 对应的bash的进程号,但是杀不掉。
kill -9 对应的bash的进程号
注意:
14.3 查看进程树pstree
- 基本语法:
pstree [选项] 可以更加直观的来看进程信息- 常用选项:
-p : 显示进程的PID
-u : 显示进程的所属用户- 应用实例:
案例1:请用树状的形式显示进程的pid。
pstree -p
案例2:请用树状的形式进程的用户id。
pstree –u
pstree -pu
14.4 服务(service)管理
- 介绍:
服务(service)
本质就是进程,但是是运行在后台的,通常都会监听某个端口,等待其它程序的请求,比如(mysql,sshd,防火墙等),因此我们又称为守护进程
,是Linux中非常重要的知识点。【原理图】- service管理指令:
service 服务名 [start | stop | restart | reload | status]
注意:在CentOS7X后,不再使用service,而是systemctl。
- 使用案例:
查看当前防火墙的状况,关闭防火墙和重启防火墙。
service iptables status- 细节讨论:
1、关闭或者启用防火墙后,立即生效。[我们可以通过Windows的telnet指令来测试某个端口是否在监听并可以访问
] 命令:telnet ip 端口
2、说明:
service iptables stop
service iptables start
这种方式只是临时生效
,当重启系统后,还是回归以前对服务的设置。
如果希望设置某个服务自启动或关闭永久生效,要使用chkconfig指令
。
14.4.1 查看服务名称
- 查看服务名称:
方式1:使用setup -> 系统服务
就可以看到。
在Linux的命令行中输入:setup 回车
选择 系统服务 回车,服务前面显示星号
表示的该服务已启动
方式2:查看/etc/init.d/服务名称
14.4.2 服务的运行级别(runlevel)
一个思考题:
如果不小心将默认的运行级别设置成 0 或者 7 ,怎么处理?
别怕,进入单用户模式,修改成正常的即可!
14.5 chkconfig指令
- 介绍:
通过chkconfig命令可以给每个服务的各个运行级别设置自启动/关闭。- 基本语法:
0) 查看所有服务在各个运行级别自启动/关闭的状态chkconfig --list
1) 查看某个服务在各个运行级别自启动/关闭的状态chkconfig --list | grep xxx
2) 查看某个服务在各个运行级别自启动/关闭的状态chkconfig 服务名称 --list
3) 设置某个服务,在某个运行级别,开启或关闭chkconfig --level 5 服务名称 on/off
例如:设置sshd服务在1运行级别时on。chkconfig --level 1 sshd off/on
4) 设置某个服务,开启或关闭chkconfig 服务名称 on/off
例如:使iptables彻底关闭。chkconfig iptables off
[不管是哪个级别都关闭]chkconfig iptables off
表示在所有level下关闭防火墙chkconfig iptables on
表示在所有level下开启防火墙- 应用实例:
14.5 动态监控进程
- 介绍:
top与ps命令很相似。它们都用来显示正在执行的进程。top与ps最大的不同之处,在于top在执行一段时间可以更新正在运行的的进程(默认每3秒变化一次)
。- 基本语法:
top [选项]- 选项说明:
- 交互操作说明:
- 应用实例:
案例1:如何监视特定用户
top:输入此命令,按回车键,查看执行的进程。
u:然后输入“u”回车,再输入用户名,即可。
案例2:如何终止指定的进程。
top:输入此命令,按回车键,查看执行的进程。
k:然后输入“k”回车,再输入要结束的进程ID号,即可。
案例3:指定系统状态更新的时间(每隔10秒自动更新)。
top -d 10
指定系统更新进程的时间为10秒。
14.6 监控网络状态
- 介绍:
netstat指令 用于查看系统网络情况- 基本语法:
netstat [选项]- 选项说明:
-an 按一定顺序排列输出
-p 显示哪个进程在调用- 应用案例:
1、查看服务名称为sshd的服务的信息。
命令:netstat –anp | grep sshd
2、查看占用22端口的进程。
命令:netstat –anp | grep 22
15 软件包管理
15.1 rpm包的管理
- 介绍:
一种用于互联网下载包的打包及安装工具,它包含在某些Linux分发版中
。它生成具有.RPM扩展名的文件
。RPM是RedHat Package Manager(RedHat软件包管理工具)
的缩写,类似windows的setup.exe,这一文件格式名称虽然打上了RedHat的标志,但理念是通用的。
Linux的分发版本都有采用(suse、redhat、centos等等),可以算是公认的行业标准了。- rpm包的简单查询指令:
查询已安装的rpm列表rpm –qa | grep xxx
例如:rpm -qa | grep firefox
- rpm包名基本格式:
一个rpm包名:firefox-45.0.1-1.el6.centos.x86_64.rpm
名称:firefox
版本号:45.0.1-1
适用操作系统:el6.centos.x86_64,表示centos6.x的64位系统,如果是i686、i386表示32位系统,noarch表示通用
。- rpm包的其它查询指令:
rpm -qa 查询所安装的所有rpm软件包
rpm -qa | more 分页查询所安装的所有rpm软件包
rpm -qa | grep xxx 例如:rpm -qa | grep firefox
rpm -q 软件包名 查询rpm软件包是否安装,例如:rpm -q firefox
rpm -qi 软件包名 查询rpm软件包信息。例如:rpm -qi filefox
rpm -ql 软件包名 查询软件包中的文件,例如:rpm -ql firefox
rpm -qf 文件全路径名 查询文件所属的软件包,例如:rpm -qf /etc/passwd
或者rpm -qf /root/install.log
15.2 卸载rpm包
- 基本语法:
rpm -e rpm包的名称- 应用案例:
删除firefox软件包rpm -e firefox
- 细节讨论:
1) 如果其它软件包依赖于您要卸载的软件包,卸载时则会产生错误信息。
如:rpm -e foo
removing these packages would break dependencies:foo is needed by bar-1.0-1
2) 如果我们就是要删除foo这个rpm 包,可以增加参数--nodeps
,就可以强制删除,但是一般不推荐这样做,因为依赖于该软件包的程序可能无法运行。
如:rpm -e --nodeps foo
[小心使用]
15.3 安装rpm包
- 基本语法:
rpm -ivh rpm包全路径名称- 参数说明:
-i=install 安装
-v=verbose 提示
-h=hash 进度条
--nodeps 不检测依赖进度- 应用实例:
演示卸载和安装firefox浏览器。
提示:很多的rpm包,就在我们的centos安装的镜像文件中。
安装firefox浏览器步骤:
- 1、先找到firefox的安装rpm包,可以挂载上我们的CentOS的ISO文件,也可以从网络上下载firefox的安装rpm包。我们演示的是挂载上我们的CentOS的ISO文件。
- 2、然后到/media/目录中找到irefox的安装rpm包。
- 3、执行安装命令。
按照下图进行操作
此时会发现Linux桌面上出现一个光驱
具体安装过程:
15.4 yum包的管理
- 介绍:
yum 是一个 Shell 前端软件包管理器
。基于RPM包管理,能够从指定的服务器自动下载rpm包并且安装,可以自动处理依赖性关系
,并且一次安装所有依赖的软件包
。- yum的基本指令:
1、查询yum服务器是否有需要安装的软件(一般显示的是最新版本的)
yum list | grep xxx 查看软件列表
2、安装指定的yum包
yum install xxx 下载安装- yum应用实例:
案例:请使用yum的方式来安装firefox指令。
yum install firefox
//会自动的下载安装适合你系统的最新版本
16 大厂面试题
16.1 百度面试题
问题:Linux常用命令,至少6个
答:netstat、top、lsblk、find、ps、chkconfig。
16.2 瓜子二手车面试题
问题:Linux查看内存、磁盘存储情况、磁盘io读写情况、端口占用、进程等命令。
答:
top
df -lh
netstat -tunlp
ps –aux | grep 进程名
iotop 如果没有该命令,就先yum安装一把
查看端口占用情况:netstat -tunlp
查看磁盘io读写:iotop
17 感悟分享
唐朝有《卖炭翁》--背后有故事,以后深究之。
宋朝有《卖油翁》--背后有故事,以后深究之。
陈康肃公尧咨善射,当世无双,公亦以此自矜。尝射于家圃,有卖油翁释担而立,睨之,久而不去。见其发矢十中八九,但微颔之。康肃问曰:“汝亦知射乎?吾射不亦精乎?”翁曰:“
无他,但手熟尔。
”康肃忿然曰:“尔安敢轻吾射?”翁曰:“以我酌油知之。”乃取一葫芦置于地,以钱覆其口,徐以杓酌油沥之,自钱孔入,而钱不湿。因曰:“我亦无他,惟手熟尔。
”康肃笑而遣之。
《卖油翁》这则故事的作者是欧阳修,出自他的私家笔记《归田录》。
老黄牛精神
18 资料附录
- 尚硅谷大数据之Linux视频
链接:https://pan.baidu.com/s/1wMTp4_Fh9Yl1CPjUNOydaw
密码:6q4k
视频质量:优良
视频总个数:53个
视频总时长:15:01:16
建议学习时长:5天
原文地址:https://www.cnblogs.com/chenmingjun/p/10325450.html