- i386:
- i586:Intel Pentium MMX与AMD k6年代的CPU
- i686:intel Celeron与AMD k7年代的32位CPU
- x86_64:目前的64位CPU的统称
- 由里到外:硬件、OS核心、系统调用、应用程序
- Linux 内的所有数据都是以文件的形态来呈现的
- 在 Linux 系统中,每个装置都被当成一个文件来对待;
- 几乎所有的硬件装置文件都在/dev 这个目录内;
- 正常的实体机器大概使用的都是 /dev/sd[a-] 的磁盘文件名,至于虚拟机环境底下,为了加速,可能就会使用 /dev/vd[a-p] 这种装置文件名喔!
- 由于 SATA/USB/SAS 等磁盘接口都是使用 SCSI 模块来驱动的, 因此这些接口的磁盘装置文件名都是/dev/sd[a-p]的格式。
-
环境变量PATH
- 系统会依照 PATH 的设定去每个 PATH 定义的目录下搜寻文件名为 ls 的可执行文件, 如果在 PATH 定义的目录中含有多个文件名为 ls 的可执行文件,那么先搜寻到的同名指令先被执行。
- echo $PATH 来看看到底有哪些目录被定义出来了( PATH 前面加的 $ 表示后面接的是变量)
- 不同身份使用者预设的 PATH 不同,默认能够随意执行的指令也不同
- 添加路径到PATH中:
export PATH="${PATH}:/root"
,把路径/root
添加到PATH中
-
修改PATH路径的几种方法
- 在终端输入:
export PATH=/usr/local/mongodb/bin:$PATH
,对当前用户立即生效,重启后失效; - 通过修改
~/.bashrc
文件(添加上面的语句),重启或输入:source ~/.bashrc
生效,对当前用户永久有效; - 通过修改profile文件,重启后对所有用户永久有效;
- 修改
/etc/environment
文件,重启后对所有用户永久有效;
- 在终端输入:
-
MBR(maser boot record)中包含两个部分(MBR只是一个位置的称呼):主要启动记录区、分区表。其中分区表只有64字节,只能保存4组分区信息(每个扇区的起始柱号与结束柱号)。但因为可以在每个分区前保存本分区的逻辑分区信息,所以理论上以MBR为例,我们可以把硬盘分无数个分区。MBR中的分区有两种,主分区与逻辑分区,具体的分辨方法很简单。
- MBR中每个分区记录只有16字节所以无法获得分区大于2.2T的分区,且MBR方式也无法完全利用大于2.2T的硬盘;
- MBR只有一个分区记录区块,所以如果被破坏了硬盘难以恢复;
- MBR每个分区容量最大为:
2^32 * 512 = 2T
,MBR使用32位地址。 - MBR内存放的开机管理程序仅仅446字节;
-
GPT(GUID partition table):以LBA(Logical Block Address)作为基本划分,LBA的大小可以设定。第一个LBA称为LBA0,GPT使用了34个LBA来记录分区信息,并使用整个磁盘最后33个LBA作为分区信息备份。为了与MBR相容,LBA0作为传统的MBR区域,但LBA0最后几个字节即MBR分区信息记录区内会放入特殊的标志用于区分当前硬盘的分区格式为GPT。(GPT一般可以对磁盘分128个区)
- 对于GPT,每个LBA中有四个分区记录,所以一般而言每个分区记录可以有不少于512/4=128个字节。因为GPT中有32个LBA用于保存分区信息所以GPT一般最多可以分128个分区。
- GPT分区表一个槽最大容量约为
2^64 * 512 = 2^33 T
,GPT使用64位地址; - linux安装时可以强制使用GPT分区方式;
- BIOS:开机主动执行的韧体,会认识第一个可开机的装置;
- MBR:第一个可开机装置的第一个扇区内的主要启动记录区块,内含开机管理程序;
- 开机管理程序(boot loader,位于MBR中):一支可读取核心文件来执行的软件;
- 核心文件(由开机管理程序载入内存中):开始操作系统的功能...
- UEFI相当于一个小型的操作系统
-
权限管理内容【参考】:
-rw-r--r--. 1 root root 1864 May 4 18:01 initial-setup-ks.cfg [[文件类型] [连接数][所有者] [所属群组] [大小] [修改时间] [文件名] [所有者权限] [群组权限] [其他使用者权限]]
-
rwx(421)的意义
- 文件
- r:读
- w:更改内容
- x:如果是可执行文件,则可执行
- 目录(目录也是一种文件,其中包含了目录中文件或子目录的名称等)
- r:具有读取目录结构列表的权限
- w:具有改动该目录结构列表的权限(建立、删除、更名、移动。如果没有x权限,左边的动作依旧无法实现。)
- x:具有进入该目录成为工作目录的权限(例如cd进入当前文件夹)
- 文件
-
chown、chgrp、chmod
-
umask:用户创建文件夹与文件时对应文件的默认权限由umask决定。umask显示的是去除的权限,例如umask返回0002则表示其他用户没有写的权限
-
除了常见的rwx属性,linux在Ext2/3/4传统文件系统上还有其他隐藏的属性,一般使用chattr与lsattr来实现设定与查询,xfs仅支持部分的隐藏属性。
-
特殊权限
- set UID:状态:『-rwsr-xr-x』,此时就被称为 Set UID,简称为 SUID 的特殊权限。
- SUID 权限仅对二进制程序(binary program)有效;
- 执行者对于该程序需要具有 x 的可执行权限;
- 本权限仅在执行该程序的过程中有效 (run-time);
- 执行者将具有该程序拥有者 (owner) 的权限。
- Set GID: s 在群组的 x 时则称为 Set GID,其功能与SUID类似,只不过对应的是群组。
- SGID 对二进制程序有用;
- 程序执行者对于该程序来说,需具备 x 的权限;
- 执行者在执行的过程中将会获得该程序群组的支持!
- Sticky Bit :SBIT 目前只针对目录有效
- 当用户对于此目录具有 w, x 权限,亦即具有写入的权限时
- 当用户在该目录下建立文件或目录时,仅有自己与 root 才有权力删除该文件
- SUID为4、SGID为2、SBIT为1
- chmod 4755 filename //第一个4用于设定SUID,其他的类似
chmod u=rwxs,go=x test
chmod g+s,o+t test
- set UID:状态:『-rwsr-xr-x』,此时就被称为 Set UID,简称为 SUID 的特殊权限。
-
Linux文件系统系统的断电保护
为了防止系统突然断电等情况造成系统文件不一致的情况,有些系统引入了文件系统日志,在这样的程序当中,万一数据的纪录过程当中发生了问题,那么我们的系统只要去检查日志记录区块,就可以知道哪个文件发生了问题,针对该问题来做一致性的检查即可
- 预备:当系统要写入一个文件时,会先在日志记录区块中记录某个文件准备要写入的信息;
- 实际写入:开始写入文件的权限与数据;开始更新 metadata 的数据;
- 结束:完成数据与 metadata 的更新后,在日志记录区块当中完成该文件的纪录。
-
Linux中的写穿透(非实时)
当系统加载一个文件到内存后,如果该文件没有被更动过,则在内存区段的文件数据会被设定为干净(clean)的。 但如果内存中的文件数据被更改过了,此时该内存中的数据会被设定为脏的(Dirty)。此时所有的动作都还在内存中执行,并没有写入到磁盘中。系统会不定时的将内存中设定为『Dirty』的数据写回磁盘,当然也可以使用指令sync来强制写回。
-
XFS文件系统是centos7预设的文件系统,其取代了以前常用的EXT4,XFS相对EXT4更适合大磁盘。
-
Linux下的分区概念
传统的磁盘与文件系统之应用中,一个分区槽就是只能够被格式化成为一个文件系统,所以我们可以说一个 filesystem 就是一个 partition。但是由于新技术的利用,例如我们常听到的 LVM 与软件磁盘阵列(software raid), 这些技术可以将一个分区槽格式化为多个文件系统(例如 LVM),也能够将多个分区槽合成一个文件系统(LVM, RAID)
- 参加鸟叔的232页
- usr:unix software resource
-
ext2的基本组成
- superblock:记录此 filesystem 的整体信息,包括 inode/block 的总量、使用量、剩余量, 以及文件系统的格式与相关信息等;
- 文件系统描述说明;
- 区块对照表(block与inode);
- inode:记录文件的属性(不包括文件名),一个文件占用一个 inode,同时记录此文件的数据所在的 block 号码;
- block:实际记录文件的内容,若文件太大时,会占用多个 block 。
由于每个 inode 与 block 都有编号,而每个文件都会占用一个 inode ,inode 内则有文件数据放置的 block 号码。 因此,我们可以知道的是,如果能够找到文件的 inode 的话,那么自然就会知道这个文件所放置数据的 block 号码, 当然也就能够读出该文件的实际数据了。
将所有的 inode 与 block 通通放置在一起将是很不智的决定,因为 inode 与 block 的数量太庞大,不容易管理。 为此之故,Ext2 文件系统在格式化的时候基本上是区分为多个区块群组 (block group) 的,每个区块群组都有独立的 inode/block/superblock 系统。
对于一个filesystem而言可能其拥有多个superblock,但一般而言只有第一个有效,其他都是第一个superblock的备份。
-
碎片整理:需要碎片整理的原因就是文件写入的 block 太过于离散了,此时文件读取的效能将会变的很差所致。 这个时候可以透过碎片整理将同一个文件所属的 blocks 汇整在一起,这样数据的读取会比较容易!FAT文件系统没有inode的概念,所以系统只有读完所有block(block像链表一样组织)才会知道文件的具体信息,所以碎片整理对FAT文件系统很重要。
-
在 Ext2 文件系统中所支持的 block 大小有 1K, 2K 及 4K 三种而已
Block大小 1KB 2KB 4KB 最大单一文件限制 16GB 256GB 2TB 最大文件系统总容量 2TB 8TB 16TB
- inode中的成员
- 该文件的存取模式(read/write/excute);
- 该文件的拥有者与群组(owner/group);
- 该文件的容量;
- 该文件建立或状态改变的时间(ctime);
- 最近一次的读取时间(atime);
- 最近修改的时间(mtime);
- 定义文件特性的旗标(flag),如 SetUID...;
- 该文件真正内容的指向 (pointer);
- inode的特点
- 每个 inode 大小均固定为 128 bytes (新的 ext4 与 xfs 可设定到 256 bytes);
- 每个文件都仅会占用一个 inode 而已;
- 承上,因此文件系统能够建立的文件数量与 inode 的数量有关;
- 系统读取文件时需要先找到 inode,并分析 inode 所记录的权限与用户是否符合,若符合才能够开始实际读取 block 的内容。
- 以1K大小的block来计算ext2中一个inode所能表示的最大文件(ext4会大很多)
- 12个直接指向: 12*1K=12K
- 间接:
256*1K=256K
- 双间接:
256*256*1K=256^2 K
- 三间接:
256*256*256*1K=256^3K
- 总和:
12 + 256 + 256*256 + 256*256*256 (K) = 16GB
- inode 本身并不记录文件名,文件名的记录是在目录的 block 当中,目录的block中有文件的名称和对应文件的inode。
- 一般来说, superblock 的大小为 1024bytes。
- 每个 block group 都可能含有 superblock 喔!但是我们也说一个文件系统应该仅有一个superblock 而已,那是怎么回事啊? 事实上除了第一个 block group 内会含有 superblock 之外,后续的 block group 不一定含有 superblock , 而若含有 superblock 则该 superblock 主要是做为第一个 block group 内 superblock 的备份咯,这样可以进行 superblock 的救援。
- superblock中包含的内容如下
- block 与 inode 的总量;
- 未使用与已使用的 inode / block 数量;
- block 与 inode 的大小 (block 为 1, 2, 4K,inode 为 128bytes 或 256bytes);
- filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘 (fsck) 的时间等文件系统的相关信息;
- 一个 valid bit 数值,若此文件系统已被挂载,则 valid bit 为 0 ,若未被挂载,则 valid bit 为 1 。
这个区段可以描述每个 block group 的开始与结束的 block 号码,以及说明每个区段(superblock, bitmap, inodemap, data block) 分别介于哪一个 block 号码之间。这部份也能够用 dumpe2fs 来观察的。
从 block bitmap 当中可以知道哪些 block 是空的,因此我们的系统就能够很快速的找到可 使用的空间来处置文件啰
inode bitmap 则是记录使用与未使用的 inode 号码
- 查询 Ext 家族 superblock 信息的指令
-
当我们在 Linux 下的文件系统建立一个目录时,文件系统会分配一个inode与至少一块block给该目录。其中,inode 记录该目录的相关权限与属性,并可记录分配到的那块 block 号码; 而 block 则是记录在这个目录下的文件名与该文件名占用的 inode 号码数据。
inode number 文件名 53735697 anaconda-ks.cfg 53745858 initial-setup-ks.cfg ...
- 每个 filesystem 都有独立的 inode / block / superblock 等信息,这个文件系统要能够链接到目录树才能被我们使用。 将文件系统与目录树结合的动作我们称为『挂载』。挂载点一定是目录,该目录为进入该文件系统的入口
-
hard link:不同的文件名指向相同的inode,inode中的连接数会指名连接个数(类似于引用计数)。
-
soft link:类似于windows下的快捷方式。 Symbolic link 就是在建立一个独立的文件,而这个文件会让数据的读取指向他 link 的那个文件的档名。由 Symbolic link 所建立的文件为一个独立的新的文件,所以会占用掉 inode 与 block。
-
由于 Hard Link 的限制太多了,包括无法做『目录』的 link , 所以在用途上面是比较受限的!反而是 Symbolic Link 的使用方面较广喔
-
hard link无法链接目录的一个原因:
目录与文件的一个区别是目录保存着其父目录的位置和自己的位置,而文件自身是不保存位置信息的。如果允许目录的hard link,则同一个目录必然有两个不同的父目录,这与常理不合。还有就是如果允许目录的hrad link,系统中很容易出现目录的循环引用。还有其他的原因,可以参考这里。
-
目录中的link数
当我们在一个文件夹中创建一个文件夹时,父目录中的link数会加1,因为一个目录中最少有两个目录:.和..,其中..指向的就是其父目录。
- 判断一个指令是否內建于BASH的方式:type [-tpa] name
- BASH使用反斜杠表示换行(反斜杠后除换行键外不能有其他字符),反斜杠在BASH中表示‘跳脱’
- 指令的快速修改指令:
- [ctrl]+u/[ctrl]+k 分别是从光标处向前删除指令串 ([ctrl]+u) 及向后删除指令串 ([ctrl]+k)。
- [ctrl]+a/[ctrl]+e 分别是让光标移动到整个指令串的最前面 ([ctrl]+a) 或最后面 ([ctrl]+e)。
- 在 Linux 预设的情况中,使用{大写的字母}来设定的变量一般为系统内定需要的变量
- BASH中的变量是区分大小写的
- 在shell中输入bash将进入一个bash环境,一般的linux中的shell默认为bash,所以我们使用bash将在bash中创建一个新的bash,使用exit指令可以退出当前bash。子程序仅会继承父程序的环境变量(子shell与父shell共享一块环境变量保存区),子程序不会继承父程序的自定义变量,但我们可以使用指令export将变量变成环境变量。
- 使用locate指令改变当前环境的编码方式
- bash中变量内容的删除替换等操作参考鸟叔的linux基础篇第四版第10.2.8节
- bash中操作环境的解释见10.4节
-
在控制台输出变量的格式如下:
$PATH
或${PATH}
-
变量的设定规则(使用 env 和 export 可以获得当前环境下所有的)
- 变量与变量内容以一个等号『=』来连结
- 等号两边不能直接接空格符
- 变量名称只能是英文字母与数字,但是开头字符不能是数字
- 变量内容若有空格符可使用双引号『"』或单引号『'』将变量内容结合起来
- 双引号内的特殊字符如 $ 等,可以保有原本的特性
- 单引号内的特殊字符则仅为一般字符 (纯文本)
- 可用跳脱字符『 \ 』将特殊符号(如 [Enter], $, , 空格符, '等)变成一般字符
- 在一串指令的执行中,还需要藉由其他额外的指令所提供的信息时,可以使用反单引号『
指令
』或 『$(指令)』,例如:version=$(uname -r)
、cd /lib/modules/`uname -r`/kernel
- 若该变量为扩增变量内容时,则可用 "$变量名称" 或 ${变量} 累加内容
- 若该变量需要在其他子程序执行,则需要以 export 来使变量变成环境变量
- 取消变量的方法为使用 unset:
unset myname
-
SHELL中的一些变量
- HOME
- SHELL:返回说是用的shell,一般为/bin/bash
- HISTSIZE:历史指令记录的个数
- MAIL、PATH、LANG
- RANDOM:返回一个整型的随机数
-
$:返回当前shell的线程号(echo $ $,一般输出的是一个整数值) - ?:上一个指令的回传值
- OSTYPE, HOSTTYPE, MACHTYPE返回主机相关信息
-
SHELL中的一些函数
- read [-pt] variable,用户的输入将保存在variable中
- read -p "Please keyin your name: " -t 30 named
- declare / typeset 宣告变量的类型
-
变量类型默认为『字符串』,所以若不指定变量类型,则 1+2 为一个『字符串』而不是『计算式』。 所以上述第一个执行的结果才会出现那个情况的; bash 环境中的数值运算,预设最多仅能到达整数形态,所以 1/3 结果是 0;
sum=100+300+50 echo ${sum} declare -i sum=100+300+50 echo ${sum}
-
- ulimit:可以『限制用户的某些系统资源』的,包括可以开启的文件数量, 可以使用的 CPU 时间,可以使用的内存总量等等
- read [-pt] variable,用户的输入将保存在variable中
-
SHELL中指令的查询过程
- 以相对/绝对路径执行指令,例如『 /bin/ls 』或『 ./ls 』;
- 由 alias 找到该指令来执行;
- 由 bash 内建的 (builtin) 指令来执行;
- 透过 $PATH 这个变量的顺序搜寻到的第一个指令来执行。
-
通配符与特殊字符
- 通配符
-
*
代表『 0 个到无穷多个』任意字符 - ? 代表『一定有一个』任意字符
- [ ]同样代表『一定有一个在括号内』的字符(非任意字符)。例如 [abcd] 代表『一定有一个字符, 可能是 a, b, c, d 这四个任何一个』
- [ - ]若有减号在中括号内时,代表『在编码顺序内的所有字符』。例如 [0-9] 代表 0 到 9 之间的所有数字,因为数字的语系编码是连续的!
- [^ ] 若中括号内的第一个字符为指数符号 (^) ,那表示『反向选择』,例如 [^abc] 代表 一定有一个字符,只要是非 a, b, c 的其他字符就接受的意思。
-
- 特殊字符
-
#
批注符号:这个最常被使用在 script 当中,视为说明!在后的数据均不执行 -
\
跳脱符号:将『特殊字符或通配符』还原成一般字符 -
|
管线 (pipe):分隔两个管线命令的界定(后两节介绍); -
;
连续指令下达分隔符:连续性命令的界定 (注意!与管线命令并不相同) -
~
用户的家目录 -
$
取用变数前导符:亦即是变量之前需要加的变量取代值 -
&
工作控制 (job control):将指令变成背景下工作 -
!
逻辑运算意义上的『非』 not 的意思! -
/
目录符号:路径分隔的符号 -
>, >>
数据流重导向:输出导向,分别是『取代』与『累加』 -
<, <<
数据流重导向:输入导向 (这两个留待下节介绍) -
' '
单引号,不具有变量置换的功能 ($ 变为纯文本) -
" "
具有变量置换的功能! ($ 可保留相关功能) -
` `
两个『 ` 』中间为可以先执行的指令,亦可使用 $( ) -
( )
在中间为子 shell 的起始与结束 -
{ }
在中间为命令区块的组合!
-
- 通配符
-
重定向(标准输入为0、标准输出为1、标准出错为2)
-
输出
- 1> :以覆盖的方法将『正确的数据』输出到指定的文件或装置上;
- 1>>:以累加的方法将『正确的数据』输出到指定的文件或装置上;
- 2> :以覆盖的方法将『错误的数据』输出到指定的文件或装置上;
- 2>>:以累加的方法将『错误的数据』输出到指定的文件或装置上;
- 举例,同时将正常与错误信息写进不同的文件中
- find /home -name .bashrc > list_right 2> list_error
- /dev/null
- /dev/null 可以吃掉任何导向这个装置的信息
- 可以使用类似于
1>&2
的形式将标准输出的内容导向标准出错
-
输入
-
<
表示将原本需要由键盘输入的数据,改由文件内容来取代,例如cat > catfile < ~/.bashrc
,其意味着catfile中的内容和.bashrc一样; -
<<
代表的是『结束的输入字符』的意思。例如cat > catfile << "eof"
,只有在后面的输入中输入eof时本次输入才会结束,不用输入ctr-d强制结束输入。
-
-
-
批量的指令执行(&&和||没有优先级,均从左到右依次执行)
- 如果指令之间没有联系,可以直接使用分号间隔每个指令:
sync;sync;showtdown -h now
- cmd1 && cmd2
- 若 cmd1 执行完毕且正确执行($?=0),则开始执行 cmd2。
- 若 cmd1 执行完毕且为错误 ($?≠0),则 cmd2 不执行。
- cmd1 || cmd2
- 若 cmd1 执行完毕且正确执行($?=0),则 cmd2 不执行。
- 若 cmd1 执行完毕且为错误 ($?≠0),则开始执行 cmd2。
- 如果指令之间没有联系,可以直接使用分号间隔每个指令:
- 管线命令『 | 』(pipe)仅能处理经由前面一个指令传来的正确信息,也就是 standard output 的信息,对于stdandard error 并没有直接处理的能力。在每个管线后面接的第一个数据必定是『指令』!而且这个指令必须要能够接受 standard input 的数据才行,这样的指令才可以是为『管线命令』。
- 以grep指令为例:
grep -n 't[ae]st' regular_express.txt
grep -n '[^g]oo' regular_express.txt
grep -n '[^a-z]oo' regular_express.txt
grep -n '[0-9]' regular_express.txt
- SAMBA:文件分享软件
- DHCP
- who:查看在线用户
- netstat:联网状态,例如
netstat -a
- ps:显示程序的执行状态,例如:
ps -aux
- su - ,获得root权限(centos)
- sync:将内存中的数据同步到硬盘中。一般的关机与重启指令都会调用sync
- chmod:
chmod [u g o a] [+ - =] [r w x] file or dir
chmod u=rwx,g=rx,o=r filename
,u:user(ower)、g:group、o:otherschmod 777 .bashrc
- chgrp:
chgrp [-R] users initial-setup-ks.cfg
- chown:
chown [-R] 账号名称:组名 文件或目录
- cat:由第一行开始显示文件内容
- tac:从最后一行开始显示,可以看出 tac 是 cat 的倒着写!
- nl:显示的时候,顺道输出行号!
- more:一页一页的显示文件内容
- less:与 more 类似,但是比 more 更好的是,他可以往前翻页!
- head:只看头几行
- tail:只看尾巴几行
- od:以二进制的方式读取文件内容,od [-t TYPE] 文件
- a :利用默认的字符来输出;
- c :使用 ASCII 字符来输出
- d[size] :利用十进制(decimal)来输出数据,每个整数占用 size bytes ;
- f[size] :利用浮点数(floating)来输出数据,每个数占用 size bytes ;
- o[size] :利用八进制(octal)来输出数据,每个整数占用 size bytes ;
- x[size] :利用十六进制(hexadecimal)来输出数据,每个整数占用 size bytes ;
- touch:修改文件中的时间属性,例如修改时间,创建时间等
- file:获得文件的类型
- which:搜索脚本文件的位置,
which ls
- whereis:
whereis [-bmsu] 文件或目录名
,在特殊的文件夹中找对应的文件。whereis比find速度快,因为find是寻找一个文件夹下所有的子文件夹,而whereis只查找指定的几个文件夹。当无法使用whereis找到对应文件时再使用find。whereis -b ls
只会找名为ls的二进制文件而不找文本。 - locate:依据 /var/lib/mlocate 内的数据库记载,找出用户输入的关键词文件名。不同发行版本的系统会不定时更新一个数据库,这个数据库记录了当前文件系统中所有的文件,所以locate执行的速度很快。因为数据库的更新有很长的时间间隔,所以有时候新的文件使用locate指令是无法找到的,此时可以使用指令
updatedb
更新这个数据库。 - updatedb:根据 /etc/updatedb.conf 的设定去搜寻系统硬盘内的文件名,并更新 /var/lib/mlocate 内的数据库文件
- find:最复杂的查找指令,具体用法查看man手册
- dumpe2fs [-bh] 装置文件名
- blkid 这个指令可以叫出目前系统有被格式化的装置
- df:列出文件系统的整体磁盘使用量
- du:评估文件系统的磁盘使用量(常用在推估目录所占容量)
- cut:按照一定的规则切割字符串
- grep:分析当行中是否有我们需要的数据如果有就整行输出
- sort、uniq(剔除重复行)、wc(分析文件有多少字、多少行、多少字符)