(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)

摘要:
文件打包与压缩实验介绍Linux上常用的压缩/解压工具,介绍了zip,rar,tar的使用。后面使用du命令查看打包后文件的大小。下面先掌握tar命令一些基本的使用方式,即不进行压缩只是进行打包和解包的操作。

【所有参考资料皆来源与实验楼,特此声明】

【第六课】

文件打包与压缩

实验介绍

Linux 上常用的 压缩/解压 工具,介绍了 zip,rar,tar 的使用。

一、文件打包和解压缩

在讲 Linux 上的解压缩工具之前,有必要先了解以下常见常用的压缩包文件格式。在 Windows 上我们最常见的不外乎这三种*.zip,*.rar,*.7z后缀的压缩文件,而在 Linux 上面常见常用的除了以上这三种外,还有*.gz,*.xz,*.bz2,*.tar,*.tar.gz,*.tar.xz,*tar.bz2,简单介绍如下:

文件后缀名

说明

*.zip

zip程序打包压缩的文件

*.rar

rar程序压缩的文件

*.7z

7zip程序压缩的文件

*.tar

tar程序打包,未压缩的文件

*.gz

gzip程序(GNU zip)压缩的文件

*.xz

xz程序压缩的文件

*.bz2

bzip2程序压缩的文件

*.tar.gz

tar打包,gzip程序压缩的文件

*.tar.xz

tar打包,xz程序压缩的文件

*tar.bz2

tar打包,bzip2程序压缩的文件

*.tar.7z

tar打包,7z程序压缩的文件

讲了这么多种压缩文件,这么多个命令,不过我们一般只需要掌握几个命令即可,包括zip,rar,tar。下面会依次介绍这几个命令及对应的解压命令。

1.zip压缩打包程序

  • 使用zip打包文件夹:

$ zip -r -q -o shiyanlou.zip /home/shiyanlou

$ du -h shiyanlou.zip

$ file shiyanlou.zip

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第1张

上面命令将 shiyanlou 的 home 目录打包成一个文件,并查看了打包后文件的大小和类型。第一行命令中,-r参数表示递归打包包含子目录的全部内容,-q参数表示为安静模式,即不向屏幕输出信息,-o,表示输出文件,需在其后紧跟打包输出文件名。后面使用du命令查看打包后文件的大小(后面会具体说明该命令)。

  • 设置压缩级别为9和1(9最大,1最小),重新打包:

$ zip -r -9 -q -o shiyanlou_9.zip /home/shiyanlou -x ~/*.zip

$ zip -r -1 -q -o shiyanlou_1.zip /home/shiyanlou -x ~/*.zip

这里添加了一个参数用于设置压缩级别-[1-9],1表示最快压缩但体积大,9表示体积最小但耗时最久。最后那个-x是为了排除我们上一次创建的 zip 文件,否则又会被打包进这一次的压缩文件中,注意:这里只能使用绝对路径,否则不起作用

我们再用du命令分别查看默认压缩级别、最低、最高压缩级别及未压缩的文件的大小:

$ du -h -d 0 *.zip ~ | sort

通过man 手册可知:

  • h, --human-readable(顾名思义,你可以试试不加的情况)
  • d, --max-depth(所查看文件的深度)

这样一目了然,你可以看到默认压缩级别应该是最高的,效果很明显,不过你在环境中操作之后看到的大小可能跟图上的有些不同,因为在你使用过程中,会随时还生成一些缓存文件在当前用户的家目录中,这对于我们学习命令使用来说,是无关紧要的,可以忽略这些不同。

  • 创建加密zip包

使用-e参数可以创建加密压缩包:

$ zip -r -e -o shiyanlou_encryption.zip /home/shiyanlou

注意:关于zip命令,因为 Windows 系统与 Linux/Unix 在文本文件格式上的一些兼容问题,比如换行符(为不可见字符),在 Windows 为 CR+LF(Carriage-Return+Line-Feed:回车加换行),而在 Linux/Unix 上为 LF(换行),所以如果在不加处理的情况下,在 Linux 上编辑的文本,在 Windows 系统上打开可能看起来是没有换行的。如果你想让你在 Linux 创建的 zip 压缩文件在 Windows 上解压后没有任何问题,那么你还需要对命令做一些修改:

$ zip -r -l -o shiyanlou.zip /home/shiyanlou

需要加上-l参数将LF转换为CR+LF来达到以上目的。

2.使用unzip命令解压缩zip文件

将shiyanlou.zip解压到当前目录:

$ unzip shiyanlou.zip

使用安静模式,将文件解压到指定目录:

$ unzip -q shiyanlou.zip -d ziptest

上述指定目录不存在,将会自动创建。如果你不想解压只想查看压缩包的内容你可以使用-l参数:

$ unzip -l shiyanlou.zip

注意:使用unzip解压文件时我们同样应该注意兼容问题,不过这里我们关心的不再是上面的问题,而是中文编码的问题,通常 Windows 系统上面创建的压缩文件,如果有有包含中文的文档或以中文作为文件名的文件时默认会采用 GBK 或其它编码,而 Linux 上面默认使用的是 UTF-8 编码,如果不加任何处理,直接解压的话可能会出现中文乱码的问题(有时候它会自动帮你处理),为了解决这个问题,我们可以在解压时指定编码类型。

使用-O(英文字母,大写o)参数指定编码类型:

unzip -O GBK 中文压缩文件.zip

3.rar打包压缩命令

rar也是 Windows 上常用的一种压缩文件格式,在 Linux 上可以使用rar和unrar工具分别创建和解压 rar 压缩包。

  • 安装rar和unrar工具:

$ sudo apt-get update

$ sudo apt-get install rar unrar

  • 从指定文件或目录创建压缩包或添加文件到压缩包:

$ rm *.zip

$ rar a shiyanlou.rar .

上面的命令使用a参数添加一个目录~到一个归档文件中,如果该文件不存在就会自动创建。

注意:rar 的命令参数没有-,如果加上会报错。

  • 从指定压缩包文件中删除某个文件:

$ rar d shiyanlou.rar .zshrc

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第2张

  • 查看不解压文件:

$ rar l shiyanlou.rar

  • 使用unrar解压rar文件

全路径解压:

$ unrar x shiyanlou.rar

去掉路径解压:

$ mkdir tmp

$ unrar e shiyanlou.rar tmp/

rar命令参数非常多,上面只涉及了一些基本操作

4.tar打包工具

在 Linux 上面更常用的是tar工具,tar 原本只是一个打包工具,只是同时还是实现了对 7z,gzip,xz,bzip2 等工具的支持,这些压缩工具本身只能实现对文件或目录(单独压缩目录中的文件)的压缩,没有实现对文件的打包压缩,所以我们也无需再单独去学习其他几个工具,tar 的解压和压缩都是同一个命令,只需参数不同,使用比较方便。

下面先掌握tar命令一些基本的使用方式,即不进行压缩只是进行打包(创建归档文件)和解包的操作。

  • 创建一个 tar 包:

$ tar -cf shiyanlou.tar ~

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第3张

上面命令中,-c表示创建一个 tar 包文件,-f用于指定创建的文件名,注意文件名必须紧跟在-f参数之后,比如不能写成tar -fc shiyanlou.tar,可以写成tar -f shiyanlou.tar -c ~。你还可以加上-v参数以可视的的方式输出打包的文件。上面会自动去掉表示绝对路径的/,你也可以使用-P保留绝对路径符。

  • 解包一个文件(-x参数)到指定路径的已存在目录(-C参数):

$ mkdir tardir

$ tar -xf shiyanlou.tar -C tardir

  • 只查看不解包文件-t参数:

$ tar -tf shiyanlou.tar

  • 保留文件属性和跟随链接(符号链接或软链接),有时候我们使用tar备份文件当你在其他主机还原时希望保留文件的属性(-p参数)和备份链接指向的源文件而不是链接本身(-h参数):

$ tar -cphf etc.tar /etc

对于创建不同的压缩格式的文件,对于tar来说是相当简单的,需要的只是换一个参数,这里我们就以使用gzip工具创建*.tar.gz文件为例来说明。

  • 我们只需要在创建 tar 文件的基础上添加-z参数,使用gzip来压缩文件:

$ tar -czf shiyanlou.tar.gz ~

  • 解压*.tar.gz文件:

$ tar -xzf shiyanlou.tar.gz

现在我们要使用其他的压缩工具创建或解压相应文件只需要更改一个参数即可:

压缩文件格式

参数

*.tar.gz

-z

*.tar.xz

-J

*tar.bz2

-j

tar 命令的参数很多,不过常用的就是上述这些,需要了解更多你可以查看 man 手册获取更多帮助。

作业

天冷的时候,要是有个火炉就好了。这里有个有趣的程序:

$ sudo apt-get install libaa-bin

# 提示command not found,请自行解决

$ aafire

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第4张

【第七课】

文件系统操作与磁盘管理

一、简单文件系统操作

1.查看磁盘和目录的容量

使用 df 命令查看磁盘的容量

$ df

在实验楼的环境中你将看到如下的输出内容:

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第5张

一般使用情况下,我们更多只是关心第一行的内容也就是环境中的rootfs或者物理主机上的/dev/sda2

"rootfs" : (Root File System)它是 Ramfs(Ramfs 是一个非常简单的 Linux 文件系统用于实现磁盘缓存机制作为动态可调整大小的基于 ram 的文件系统)或者 tmpfs 的一个特殊实例,它作为系统启动时内核载入内存之后,在挂载真正的的磁盘之前的一个临时文件系统。通常的主机会在系统启动后用磁盘上的文件系统替换,只是在一些嵌入式系统中会只存在一个 rootfs ,或者像我们目前遇到的情况运行在虚拟环境中共享主机资源的系统也可能会采用这种方式。

物理主机上的 /dev/sda2 是对应着主机硬盘的分区,后面的数字表示分区号,数字前面的字母 a 表示第几块硬盘(也可能是可移动磁盘),你如果主机上有多块硬盘则可能还会出现 /dev/sdb,/dev/sdc 这些磁盘设备都会在 /dev 目录下以文件的存在形式。

接着你还会看到"1k-blocks"这个陌生的东西,它表示以磁盘块大小的方式显示容量,后面为相应的以块大小表示的已用和可用容量,在你了解 Linux 的文件系统之前这个就先不管吧,我们以一种你应该看得懂的方式展示:

$ df -h

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第6张

现在你就可以使用命令查看你主机磁盘的使用情况了。至于挂载点如果你还记得前面第 4 节介绍 Linux 目录树结构的内容,那么你就应该能很好的理解挂载的概念,这里就不再赘述。

使用 du 命令查看目录的容量

这个命令前面其实已经用了很多次了:

# 默认同样以 blocks 的大小展示

$ du

# 加上`-h`参数,以更易读的方式展示

$ du -h

-d参数指定查看目录的深度

# 只查看1级目录的信息

$ du -h -d 0 ~

# 查看2级

$ du -h -d 1 ~

du(estimate file space usage)命令与df(report file system disk space usage)只用一字只差,首先就希望注意不要弄混淆了,以可以像我这样从man手册中获取命令的完整描述,记全称就不会搞混了。

二、简单的磁盘管理

下面涉及的命令具有一定的危险性,操作不当可能会丢失你的个人数据,初学者建议在虚拟环境中进行操作

通常情况下,这一小节应该直接将如何挂载卸载磁盘,如何格式化磁盘,如何分区,但如你所见,我们的环境中没东西给你挂,也没东西给你格和分,所以首先我们会先创建一个虚拟磁盘来进行后续的练习操作

1.创建虚拟磁盘

dd 命令简介

dd命令用于转换和复制文件,不过它的复制不同于cp。之前提到过关于 Linux 的很重要的一点,一切即文件,在 Linux 上,硬件的设备驱动(如硬盘)和特殊设备文件(如/dev/zero和/dev/random)都像普通文件一样,只要在各自的驱动程序中实现了对应的功能,dd 也可以读取自和/或写入到这些文件。这样,dd也可以用在备份硬件的引导扇区、获取一定数量的随机数据或者空数据等任务中。dd程序也可以在复制时处理数据,例如转换字节序、或在 ASCII 与 EBCDIC 编码间互换。

dd的命令行语句与其他的 Linux 程序不同,因为它的命令行选项格式为选项=值,而不是更标准的--选项 值或-选项=值。dd默认从标准输入中读取,并写入到标准输出中,但可以用选项if(input file,输入文件)和of(output file,输出文件)改变。

我们先来试试用dd命令从标准输入读入用户输入到标准输出或者一个文件:

# 输出到文件

$ dd of=test bs=10 count=1 # 或者 dd if=/dev/stdin of=test bs=10 count=1

# 输出到标准输出

$ dd if=/dev/stdin of=/dev/stdout bs=10 count=1

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第7张

上述命令从标准输入设备读入用户输入(缺省值,所以可省略)然后输出到 test 文件,bs(block size)用于指定块大小(缺省单位为 Byte,也可为其指定如'K','M','G'等单位),count用于指定块数量。如上图所示,我指定只读取总共 10 个字节的数据,当我输入了“hello shiyanlou”之后加上空格回车总共 16 个字节(一个英文字符占一个字节)内容,显然超过了设定大小。使用和du和cat命令看到的写入完成文件实际内容确实只有 10 个字节(那个黑底百分号表示这里没有换行符),而其他的多余输入将被截取并保留在标准输入。

前面说到dd在拷贝的同时还可以实现数据转换,那下面就举一个简单的例子:将输出的英文字符转换为大写再写入文件:

$ dd if=/dev/stdin of=test bs=10 count=1 conv=ucase

你可以在man文档中查看其他所有转换参数。

使用 dd 命令创建虚拟镜像文件

通过上面一小节,你应该掌握了dd的基本使用,下面就来使用dd命令来完成创建虚拟磁盘的第一步。

从/dev/zero设备创建一个容量为 256M 的空文件:

$ dd if=/dev/zero of=virtual.img bs=1M count=256

$ du -h virtual.img

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第8张

然后我们要将这个文件格式化(写入文件系统),这里我们要学到一个(准确的说是一组)新的命令来完成这个需求。

使用 mkfs 命令格式化磁盘(我们这里是自己创建的虚拟磁盘镜像)

# 进入磁盘分区模式

$ sudo fdisk virtual.img

在进行操作前我们首先应先规划好我们的分区方案,这里我将在使用 128M(可用 127M 左右)的虚拟磁盘镜像创建一个 30M 的主分区剩余部分为扩展分区包含 2 个大约 45M 的逻辑分区。

最后不要忘记输入w写入分区表。

使用 losetup 命令建立镜像与回环设备的关联

$ sudo losetup /dev/loop0 virtual.img

# 如果提示设备忙你也可以使用其它的回环设备,"ls /dev/loop*"参看所有回环设备

接着再是格式化,我们将其全部格式化为 ext4:

$ sudo mkfs.ext4 -q /dev/mapper/loop0p1

$ sudo mkfs.ext4 -q /dev/mapper/loop0p5

$ sudo mkfs.ext4 -q /dev/mapper/loop0p6

格式化完成后在/media目录下新建四个空目录用于挂载虚拟磁盘:

$ mkdir -p /media/virtualdisk_{1..3}

# 挂载磁盘分区

$ sudo mount /dev/mapper/loop0p1 /media/virtualdisk_1

$ sudo mount /dev/mapper/loop0p5 /media/virtualdisk_2

$ sudo mount /dev/mapper/loop0p6 /media/virtualdisk_3

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第9张

# 卸载磁盘分区

$ sudo umount /dev/mapper/loop0p1

$ sudo umount /dev/mapper/loop0p5

$ sudo umount /dev/mapper/loop0p6

然后:

$ df -h

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第10张

作业

cowsay命令,可以让你在终端里以一种动物说话的形式打印出一段话。

# 安装

$ sudo apt-get install cowsay

#默认是一只牛

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第11张

$ cowsay hello shiyanlou

# 加上'-l'参数打印所有支持的动物(其实不只是动物)种类

$ cowsay -l

# 使用'-f'参数选择动物种类

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第12张

$ cowsay -f elephant hello shiyanlou

# 此外它还可以结合我们之前的作业讲过的 fortune 命令一起使用

$ fortune | cowsay -f daemon

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第13张

【遇到的问题】1.加载过慢

2.找不到文件夹

【解决办法】1.刷新

2.重开虚拟环境,因为沿用上一课的环境导致这节课内容无法完成,重开即可

【第八课】

命令执行顺序控制与管道

实验介绍

顺序执行、选择执行、管道、cut 命令、grep 命令、wc 命令、sort 命令等,高效率使用 Linux 的技巧。

一、命令执行顺序的控制

1.顺序执行多条命令

通常情况下,我们每次只能在终端输入一条命令,按下回车执行,执行完成后,我们再输入第二条命令,然后再按回车执行…… 你可能会遇到如下使用场景:我需要使用apt-get安装一个软件,然后安装完成后立即运行安装的软件(或命令工具),又恰巧你的主机才更换的软件源还没有更新软件列表(比如之前我们的环境中,每次重新开始实验就得sudo apt-get update,现在已经没有这个问题了),那么你可能会有如下一系列操作:

$ sudo apt-get update

# 等待——————————然后输入下面的命令

$ sudo apt-get install some-tool

# 等待——————————然后输入下面的命令

$ some-tool

这时你可能就会想要是我可以一次性输入完,让它自己去一次执行各命令就好了,这就是我们这一小节要解决的问题。

简单的顺序执行你可以使用;来完成,比如上述操作你可以:

$ sudo apt-get update;sudo apt-get install some-tool;some-tool

# 让它自己运行

2.有选择的执行命令

关于上面的操作,不知你有没有思考过一个问题,如果我们在让它自动顺序执行命令时,前面的命令执行不成功,而后面的命令又依赖与上一条命令的结果,那么就会造成花了时间,最终却得到一个错误的结果,而且有时候直观的看你还无法判断结果是否正确。那么我们需要能够有选择性的来执行命令,比如上一条命令执行成功才继续下一条,或者不成功又该做出其它什么处理,比如我们使用which来查找是否安装某个命令,如果找到就执行该命令,否则什么也不做(虽然这个操作没有什么实际意义,但可帮你更好的理解一些概念):

$ which cowsay>/dev/null && cowsay -f head-in ohch~

你如果没有安装cowsay,你可以先执行一次上述命令,你会发现什么也没发生,你再安装好之后你再执行一次上述命令,你也会发现一些惊喜。

上面的&&就是用来实现选择性执行的,它表示如果前面的命令执行结果(不是表示终端输出的内容,而是表示命令执行状态的结果)返回0则执行后面的,否则不执行,你可以从$?环境变量获取上一次命令的返回结果:

学习过 C 语言的用户应该知道在 C 语言里面&&表是逻辑与,而且还有一个||表示逻辑或,同样 Shell 也有一个||,它们的区别就在于,shell中的这两个符号除了也可用于表示逻辑与和或之外,就是可以实现这里的命令执行顺序的简单控制。||在这里就是与&&相反的控制效果,当上一条命令执行结果为≠0($?≠0)时则执行它后面的命令:

$ which cowsay>/dev/null || echo "cowsay has not been install, please run 'sudo apt-get install cowsay' to install"

除了上述基本的使用之外,我们还可以结合这&&和||来实现一些操作,比如:

$ which cowsay>/dev/null && echo "exist" || echo "not exist"

我画个流程图来解释一下上面的流程:

思考

上面我们讲到将&&和||结合起来使用,那么是否以任意顺序都行?比如上面我们是&&在前||在后,反过来可以么?会不会有问题?

二、管道

管道是什么,管道是一种通信机制,通常用于进程间的通信(也可通过socket进行网络通信),它表现出来的形式就是将前面每一个进程的输出(stdout)直接作为下一个进程的输入(stdin)。

管道又分为匿名管道和具名管道(这里将不会讨论在源程序中使用系统调用创建并使用管道的情况,它与命令行的管道在内核中实际都是采用相同的机制)。我们在使用一些过滤程序时经常会用到的就是匿名管道,在命令行中由|分隔符表示,|在前面的内容中我们已经多次使用到了。具名管道简单的说就是有名字的管道,通常只会在源程序中用到具名管道。下面我们就将通过一些常用的可以使用管道的"过滤程序"来帮助你熟练管道的使用。

1.试用

先试用一下管道,比如查看/etc目录下有哪些文件和目录,使用ls命令来查看:

$ ls -al /etc

有太多内容,屏幕不能完全显示,这时候可以使用滚动条或快捷键滚动窗口来查看。不过这时候可以使用管道:

$ ls -al /etc | less

通过管道将前一个命令(ls)的输出作为下一个命令(less)的输入,然后就可以一行一行地看。

2.cut 命令,打印每一行的某一字段

打印/etc/passwd文件中以:为分隔符的第1个字段和第6个字段分别表示用户名和其家目录:

$ cut /etc/passwd -d ':' -f 1,6

打印/etc/passwd文件中每一行的前N个字符:

# 前五个(包含第五个)

$ cut /etc/passwd -c -5

# 前五个之后的(包含第五个)

$ cut /etc/passwd -c 5-

# 第五个

$ cut /etc/passwd -c 5

# 2到5之间的(包含第五个)

$ cut /etc/passwd -c 2-5

3.grep 命令,在文本中或 stdin 中查找匹配字符串

grep命令是很强大的,也是相当常用的一个命令,它结合正则表达式可以实现很复杂却很高效的匹配和查找,不过在学习正则表达式之前,这里介绍它简单的使用,而关于正则表达式后面将会有单独一小节介绍到时会再继续学习grep命令和其他一些命令。

grep命令的一般形式为:

grep [命令选项]... 用于匹配的表达式 [文件]...

还是先体验一下,我们搜索/home/shiyanlou目录下所有包含"shiyanlou"的所有文本文件,并显示出现在文本中的行号:

$ grep -rnI "shiyanlou" ~

-r参数表示递归搜索子目录中的文件,-n表示打印匹配项行号,-I表示忽略二进制文件。这个操作实际没有多大意义,但可以感受到grep命令的强大与实用。

当然也可以在匹配字段中使用正则表达式,下面简单的演示:

# 查看环境变量中以"yanlou"结尾的字符串

$ export | grep ".*yanlou$"

其中$就表示一行的末尾。

4. wc 命令,简单小巧的计数工具

wc 命令用于统计并输出一个文件中行、单词和字节的数目,比如输出/etc/passwd文件的统计信息:

$ wc /etc/passwd

分别只输出行数、单词数、字节数、字符数和输入文本中最长一行的字节数:

# 行数

$ wc -l /etc/passwd

# 单词数

$ wc -w /etc/passwd

# 字节数

$ wc -c /etc/passwd

# 字符数

$ wc -m /etc/passwd

# 最长行字节数

$ wc -L /etc/passwd

注意:对于西文字符来说,一个字符就是一个字节,但对于中文字符一个汉字是大于2个字节的,具体数目是由字符编码决定的

再来结合管道来操作一下,下面统计 /etc 下面所有目录数:

$ ls -dl /etc/*/ | wc -l

5.sort 排序命令

这个命令前面我们也是用过多次,功能很简单就是将输入按照一定方式排序,然后再输出,它支持的排序有按字典排序,数字排序,按月份排序,随机排序,反转排序,指定特定字段进行排序等等。

默认为字典排序:

$ cat /etc/passswd | sort

反转排序:

$ cat /etc/passwd | sort -r

按特定字段排序:

$ cat /etc/passwd | sort -t':' -k 3

上面的-t参数用于指定字段的分隔符,这里是以":"作为分隔符;-k 字段号用于指定对哪一个字段进行排序。这里/etc/passwd文件的第三个字段为数字,默认情况下是一字典序排序的,如果要按照数字排序就要加上-n参数:

$ cat /etc/passwd | sort -t':' -k 3 -n

6. uniq 去重命令

uniq命令可以用于过滤或者输出重复行。

  • 过滤重复行

我们可以使用history命令查看最近执行过的命令(实际为读取${SHELL}_history文件,如我们环境中的~/.zsh_history文件),不过你可能只想查看使用了那个命令而不需要知道具体干了什么,那么你可能就会要想去掉命令后面的参数然后去掉重复的命令:

$ history | cut -c 8- | cut -d ' ' -f 1 | uniq

然后经过层层过滤,你会发现确是只输出了执行的命令那一列,不过去重效果好像不明显,仔细看你会发现它趋势去重了,只是不那么明显,之所以不明显是因为uniq命令只能去连续重复的行,不是全文去重,所以要达到预期效果,我们先排序:

$ history | cut -c 8- | cut -d ' ' -f 1 | sort | uniq

# 或者$ history | cut -c 8- | cut -d ' ' -f 1 | sort -u

这就是 Linux/UNIX 哲学吸引人的地方,大繁至简,一个命令只干一件事却能干到最好。

  • 输出重复行

# 输出重复过的行(重复的只输出一个)及重复次数

$ history | cut -c 8- | cut -d ' ' -f 1 | sort | uniq -dc

# 输出所有重复的行

$ history | cut -c 8- | cut -d ' ' -f 1 | sort | uniq -D

文本处理命令还有很多,下一节将继续介绍一些常用的文本处理的命令。

作业

使用以前介绍过的方法,安装aview和imagemagick,然后用asciiview命令显示图片,使用方法可以用 man 命令查看。

【第十一课】

正则表达式基础

实验介绍

虽然我们这一节的标题是正则表达式,但实际这一节实验只是介绍grep,sed,awk这三个命令,而正则表达式作为这三个命令的一种使用方式(命令输出中可以包含正则表达式)。正则表达式本身的内容很多,要把它说明清楚需要单独一门课程来实现,不过我们这一节中涉及到的相关内容通常也能够满足很多情况下的需求了。

想要更深入地学习使用正则表达式,在这里正则表达式基础

一、正则表达式

什么是正则表达式呢?

正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expression,在代码中常简写为 regex、regexp 或 RE),计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。

许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在 Perl 中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由 UNIX 中的工具软件(例如sed和grep)普及开的。正则表达式通常缩写成“regex”,单数有 regexp、regex,复数有 regexps、regexes、regexen。

简单的说形式和功能上正则表达式和我们前面讲的通配符很像,不过它们之间又有很大差别,特别在于一些特殊的匹配字符的含义上,希望初学者注意不要将两者弄混淆。

1. 举例

假设我们有这样一个文本文件,包含"shiyanlou",和"shilouyan"这两个字符串,同样一个表达式:

shi*

如果这作为一个正则表达式,它将只能匹配 shi,而如果不是作为正则表达式*作为一个通配符,则将同时匹配这两个字符串。这是为什么呢?因为在正则表达式中*表示匹配前面的子表达式(这里就是它前面一个字符)零次或多次,比如它可以匹配"sh","shii","shish","shiishi"等等,而作为通配符表示匹配通配符后面任意多个任意字符,所以它可以匹配"shiyanlou",和"shilouyan"两个字符。

体验完了,下面就来开始正式学习正则表达式吧。

2.基本语法:

一个正则表达式通常被称为一个模式(pattern),为用来描述或者匹配一系列符合某个句法规则的字符串。

选择

|竖直分隔符表示选择,例如"boy|girl"可以匹配"boy"或者"girl"

数量限定

数量限定除了我们举例用的*,还有+加号,?问号,.点号,如果在一个模式中不加数量限定符则表示出现一次且仅出现一次:

  • +表示前面的字符必须出现至少一次(1次或多次),例如,"goo+gle",可以匹配"gooogle","goooogle"等;
  • ?表示前面的字符最多出现一次(0次或1次),例如,"colou?r",可以匹配"color"或者"colour";
  • *星号代表前面的字符可以不出现,也可以出现一次或者多次(0次、或1次、或多次),例如,“0*42”可以匹配42、042、0042、00042等。

范围和优先级

()圆括号可以用来定义模式字符串的范围和优先级,这可以简单的理解为是否将括号内的模式串作为一个整体。例如,"gr(a|e)y"等价于"gray|grey",(这里体现了优先级,竖直分隔符用于选择a或者e而不是gra和ey),"(grand)?father"匹配father和grandfather(这里体验了范围,?将圆括号内容作为一个整体匹配)。

语法(部分)

正则表达式有多种不同的风格,下面列举一些常用的作为 PCRE 子集的适用于perl和python编程语言及grep或egrep的正则表达式匹配规则:(由于markdown表格解析的问题,下面的竖直分隔符用全角字符代替,实际使用时请换回半角字符)

PCRE(Perl Compatible Regular Expressions中文含义:perl语言兼容正则表达式)是一个用 C 语言编写的正则表达式函数库,由菲利普.海泽(Philip Hazel)编写。PCRE是一个轻量级的函数库,比Boost 之类的正则表达式库小得多。PCRE 十分易用,同时功能也很强大,性能超过了 POSIX 正则表达式库和一些经典的正则表达式库。

字符

描述

将下一个字符标记为一个特殊字符、或一个原义字符。例如,“n”匹配字符“n”。“ ”匹配一个换行符。序列“\”匹配“”而“(”则匹配“(”。

^

匹配输入字符串的开始位置。

$

匹配输入字符串的结束位置。

{n}

n是一个非负整数。匹配确定的n。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。

{n,}

n是一个非负整数。至少匹配n。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。

{n,m}

m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。

*

匹配前面的子表达式零次或多次。例如,zo*能匹配“z”、“zo”以及“zoo”。*等价于{0,}。

+

匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。

?

匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。

?

当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。

.

匹配除“ ”之外的任何单个字符。要匹配包括“ ”在内的任何字符,请使用像“(.| )”的模式。

(pattern)

匹配pattern并获取这一匹配的子字符串。该子字符串用于向后引用。要匹配圆括号字符,请使用“(”或“)”。

x|y

匹配xy。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。

[xyz]

字符集合(character class)。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。其中特殊字符仅有反斜线保持特殊含义,用于转义字符。其它特殊字符如星号、加号、各种括号等均作为普通字符。脱字符^如果出现在首位则表示负值字符集合;如果出现在字符串中间就仅作为普通字符。连字符-如果出现在字符串中间表示字符范围描述;如果如果出现在首位则仅作为普通字符。

[^xyz]

排除型(negate)字符集合。匹配未列出的任意字符。例如,“[^abc]”可以匹配“plain”中的“plin”。

[a-z]

字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。

[^a-z]

排除型的字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。

优先级

优先级为从上到下从左到右,依次降低:

运算符

说明

转义符

(), (?:), (?=), []

括号和中括号

*、+、?、{n}、{n,}、{n,m}

限定符

^、$、任何元字符

定位点和序列

选择

更多正则表达式的内容可以参考以下链接:

regex的思导图:

二、grep模式匹配命令

上面空谈了那么多正则表达式的内容也并没有提及具体该如何使用它,实在枯燥,如果说正则表达式是一门武功话,那它也只能算得上一些口诀招式罢了,要把它真正练起来还得需要一些兵器在手才行,这里我们要介绍的grep命令以及后面要讲的sed,awk这些就该算作是这样的兵器了。

1.基本操作

grep命令用于打印输出文本中匹配的模式串,它使用正则表达式作为模式匹配的条件。grep支持三种正则表达式引擎,分别用三个参数指定:

参数

说明

-E

POSIX扩展正则表达式,ERE

-G

POSIX基本正则表达式,BRE

-P

Perl正则表达式,PCRE

不过在你没学过perl语言的大多数情况下你将只会使用到ERE和BRE,所以我们接下来的内容都不会讨论到PCRE中特有的一些正则表达式语法(它们之间大部分内容是存在交集的,所以你不用担心会遗漏多少重要内容)

在通过grep命令使用正则表达式之前,先介绍一下它的常用参数:

参数

说明

-b

将二进制文件作为文本来进行匹配

-c

统计以模式匹配的数目

-i

忽略大小写

-n

显示匹配文本所在行的行号

-v

反选,输出不匹配行的内容

-r

递归匹配查找

-A n

n为正整数,表示after的意思,除了列出匹配行之外,还列出后面的n行

-B n

n为正整数,表示before的意思,除了列出匹配行之外,还列出前面的n行

--color=auto

将输出中的匹配项设置为自动颜色显示

注:在大多数发行版中是默认设置了grep的颜色的,你可以通过参数指定或修改GREP_COLOR环境变量。

2.使用正则表达式

使用基本正则表达式,BRE

  • 位置

查找/etc/group文件中以"shiyanlou"为开头的行

$ grep 'shiyanlou' /etc/group

$ grep '^shiyanlou' /etc/group

  • 数量

# 将匹配以'z'开头以'o'结尾的所有字符串

$ echo 'zero zo zoo' | grep 'z.*o'

# 将匹配以'z'开头以'o'结尾,中间包含一个任意字符的字符串

$ echo 'zero zo zoo' | grep 'z.o'

# 将匹配以'z'开头,以任意多个'o'结尾的字符串

$ echo 'zero zo zoo' | grep 'zo*'

注意:其中 为换行符

  • 选择

# grep默认是区分大小写的,这里将匹配所有的小写字母

$ echo '1234 abcd' | grep '[a-z]'

# 将匹配所有的数字

$ echo '1234 abcd' | grep '[0-9]'

# 将匹配所有的数字

$ echo '1234 abcd' | grep '[[:digit:]]'

# 将匹配所有的小写字母

$ echo '1234 abcd' | grep '[[:lower:]]'

# 将匹配所有的大写字母

$ echo '1234 abcd' | grep '[[:upper:]]'

# 将匹配所有的字母和数字,包括0-9,a-z,A-Z

$ echo '1234 abcd' | grep '[[:alnum:]]'

# 将匹配所有的字母

$ echo '1234 abcd' | grep '[[:alpha:]]'

下面包含完整的特殊符号及说明:

特殊符号

说明

[:alnum:]

代表英文大小写字节及数字,亦即 0-9, A-Z, a-z

[:alpha:]

代表任何英文大小写字节,亦即 A-Z, a-z

[:blank:]

代表空白键与 [Tab] 按键两者

[:cntrl:]

代表键盘上面的控制按键,亦即包括 CR, LF, Tab, Del.. 等等

[:digit:]

代表数字而已,亦即 0-9

[:graph:]

除了空白字节 (空白键与 [Tab] 按键) 外的其他所有按键

[:lower:]

代表小写字节,亦即 a-z

[:print:]

代表任何可以被列印出来的字节

[:punct:]

代表标点符号 (punctuation symbol),亦即:" ' ? ! ; : # $...

[:upper:]

代表大写字节,亦即 A-Z

[:space:]

任何会产生空白的字节,包括空白键, [Tab], CR 等等

[:xdigit:]

代表 16 进位的数字类型,因此包括: 0-9, A-F, a-f 的数字与字节

注意:之所以要使用特殊符号,是因为上面的[a-z]不是在所有情况下都管用,这还与主机当前的语系有关,即设置在LANG环境变量的值,zh_CN.UTF-8的话[a-z],即为所有小写字母,其它语系可能是大小写交替的如,"a A b B...z Z",[a-z]中就可能包含大写字母。所以在使用[a-z]时请确保当前语系的影响,使用[:lower:]则不会有这个问题。

# 排除字符

$ echo 'geek|good' | grep '[^o]'

注意:当^放到中括号内为排除字符,否则表示行首。

使用扩展正则表达式,ERE

要通过grep使用扩展正则表达式需要加上-E参数,或使用egrep。

  • 数量

# 只匹配"zo"

$ echo 'zero zo zoo' | grep -E 'zo{1}'

# 匹配以"zo"开头的所有单词

$ echo 'zero zo zoo' | grep -E 'zo{1,}'

注意:推荐掌握{n,m}即可,+,?,*,这几个不太直观,且容易弄混淆。

  • 选择

# 匹配"www.shiyanlou.com"和"www.google.com"

$ echo 'www.shiyanlou.com www.baidu.com www.google.com' | grep -E 'www.(shiyanlou|google).com'

# 或者匹配不包含"baidu"的内容

$ echo 'www.shiyanlou.com www.baidu.com www.google.com' | grep -Ev 'www.baidu.com'

注意:因为.号有特殊含义,所以需要转义。

关于正则表达式和grep命令的内容就介绍这么多,下面会介绍两个更强大的工具sed和awk,但同样也正是因为这两个工具的强大,我们的内容无法包含它们的全部,这里将只对基本内容作介绍。

三、sed 流编辑器

sed工具在 man 手册里面的全名为"sed - stream editor for filtering and transforming text ",意即,用于过滤和转换文本的流编辑器。

在 Linux/UNIX 的世界里敢称为编辑器的工具,大都非等闲之辈,比如前面的"vi/vim(编辑器之神)","emacs(神的编辑器)","gedit"这些个编辑器。sed与上述的最大不同之处大于它是一个非交互式的编辑器,下面我们就开始介绍sed这个编辑器。

sed常用参数介绍

sed 命令基本格式:

sed [参数]... [执行命令] [输入文件]...

# 形如:

$ sed -i '1s/sad/happy/' test # 表示将test文件中第一行的"sad"替换为"happy"

参数

说明

-n

安静模式,只打印受影响的行,默认打印输入数据的全部内容

-e

用于在脚本中添加多个执行命令一次执行,在命令行中执行多个命令通常不需要加该参数

-f filename

指定执行filename文件中的命令

-r

使用扩展正则表达式,默认为标准正则表达式

-i

将直接修改输入文件内容,而不是打印到标准输出设备

sed编辑器的执行命令(这里”执行“解释为名词)

sed执行命令格式:

[n1][,n2]command

[n1][~step]command

# 其中一些命令可以在后面加上作用范围,形如:

$ sed -i 's/sad/happy/g' test # g表示全局范围

$ sed -i 's/sad/happy/4' test # 4表示指定行中的第四个匹配字符串

其中n1,n2表示输入内容的行号,它们之间为,逗号则表示从n1到n2行,如果为~波浪号则表示从n1开始以step为步进的所有行;command为执行动作,下面为一些常用动作指令:

命令

说明

s

行内替换

c

整行替换

a

插入到指定行的后面

i

插入到指定行的前面

p

打印指定行,通常与-n参数配合使用

d

删除指定行

sed操作举例

我们先找一个用于练习的文本文件:

$ cp /etc/passwd ~

打印指定行

# 打印2-5行

$ nl passwd | sed -n '2,5p'

# 打印奇数行

$ nl passwd | sed -n '1~2p'

行内替换

# 将输入文本中"shiyanlou" 全局替换为"hehe",并只打印替换的那一行,注意这里不能省略最后的"p"命令

$ sed -n 's/shiyanlou/hehe/gp' passwd

注意:行内替换可以结合正则表达式使用。

行间替换

$ nl passwd | grep "shiyanlou"

# 删除第21行

$ sed -n '21cwww.shiyanlou.com' passwd

关于sed命令就介绍这么多,你如果希望了解更多sed的高级用法,你可以参看如下链接:

四、awk文本处理语言

看到上面的标题,你可能会感到惊异,难道我们这里要学习的是一门“语言”么,确切的说,我们是要在这里学习awk文本处理语言,只是我们并不会在这里学习到比较完整的关于awk的内容,还是因为前面的原因,它太强大了,它的应用无处不在,我们无法在这里以简短的文字描述面面俱到,如果你有目标成为一个linux系统管理员,确实想学好awk,你一不用担心,实验楼会在之后陆续上线linux系统管理员的学习路径,里面会有单独的关于正则表达式,awk,sed等相关课程,敬请期待吧。下面的内容,我们就作为一个关于awk的入门体验章节吧,其中会介绍一些awk的常用操作。

1.awk介绍

AWK是一种优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一.其名称得自于它的创始人Alfred Aho(阿尔佛雷德·艾侯)、Peter Jay Weinberger(彼得·温伯格)和Brian Wilson Kernighan(布莱恩·柯林汉)姓氏的首个字母.AWK程序设计语言,三位创建者已将它正式定义为“样式扫描和处理语言”。它允许您创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。最简单地说,AWK是一种用于处理文本的编程语言工具。

在大多数linux发行版上面,实际我们使用的是gawk(GNU awk,awk的GNU版本),在我们的环境中ubuntu上,默认提供的是mawk,不过我们通常可以直接使用awk命令(awk语言的解释器),因为系统已经为我们创建好了awk指向mawk的符号链接。

$ ll /usr/bin/awk

nawk: 在 20 世纪 80 年代中期,对 awk语言进行了更新,并不同程度地使用一种称为 nawk(new awk) 的增强版本对其进行了替换。许多系统中仍然存在着旧的awk 解释器,但通常将其安装为 oawk (old awk) 命令,而 nawk 解释器则安装为主要的 awk 命令,也可以使用 nawk 命令。Dr. Kernighan 仍然在对 nawk 进行维护,与 gawk 一样,它也是开放源代码的,并且可以免费获得; gawk: 是 GNU Project 的awk解释器的开放源代码实现。尽管早期的 GAWK 发行版是旧的 AWK 的替代程序,但不断地对其进行了更新,以包含 NAWK 的特性; mawk 也是awk编程语言的一种解释器,mawk遵循 POSIX 1003.2 (草案 11.3)定义的 AWK 语言,包含了一些没有在AWK 手册中提到的特色,同时 mawk 提供一小部分扩展,另外据说mawk是实现最快的awk

2.awk的一些基础概念

awk所有的操作都是基于pattern(模式)—action(动作)对来完成的,如下面的形式:

$ pattern {action}

你可以看到就如同很多编程语言一样,它将所有的动作操作用一对{}花括号包围起来。其中pattern通常是是表示用于匹配输入的文本的“关系式”或“正则表达式”,action则是表示匹配后将执行的动作。在一个完整awk操作中,这两者可以只有其中一个,如果没有pattern则默认匹配输入的全部文本,如果没有action则默认为打印匹配内容到屏幕。

awk处理文本的方式,是将文本分割成一些“字段”,然后再对这些字段进行处理,默认情况下,awk以空格作为一个字段的分割符,不过这不是固定了,你可以任意指定分隔符,下面将告诉你如何做到这一点。

3.awk命令基本格式

awk [-F fs] [-v var=value] [-f prog-file | 'program text'] [file...]

其中-F参数用于预先指定前面提到的字段分隔符(还有其他指定字段的方式) ,-v用于预先为awk程序指定变量,-f参数用于指定awk命令要执行的程序文件,或者在不加-f参数的情况下直接将程序语句放在这里,最后为awk需要处理的文本输入,且可以同时输入多个文本文件。现在我们还是直接来具体体验一下吧。

4.awk操作体验

先用vim新建一个文本文档

$ vim test

包含如下内容:

I like linux

www.shiyanlou.com

  • 使用awk将文本内容打印到终端

# "quote>" 不用输入

$ awk '{

> print

> }' test

# 或者写到一行

$ awk '{print}' test

说明:在这个操作中我是省略了patter,所以awk会默认匹配输入文本的全部内容,然后在"{}"花括号中执行动作,即print打印所有匹配项,这里是全部文本内容

  • 将test的第一行的每个字段单独显示为一行

$ awk '{

> if(NR==1){

> print $1 " " $2 " " $3

> } else {

> print}

> }' test

# 或者

$ awk '{

> if(NR==1){

> OFS=" "

> print $1, $2, $3

> } else {

> print}

> }' test

说明:你首先应该注意的是,这里我使用了awk语言的分支选择语句if,它的使用和很多高级语言如C/C++语言基本一致,如果你有这些语言的基础,这里将很好理解。另一个你需要注意的是NR与OFS,这两个是awk内建的变量,NR表示当前读入的记录数,你可以简单的理解为当前处理的行数,OFS表示输出时的字段分隔符,默认为" "空格,如上图所见,我们将字段分隔符设置为 换行符,所以第一行原本以空格为字段分隔的内容就分别输出到单独一行了。然后是$N其中N为相应的字段号,这也是awk的内建变量,它表示引用相应的字段,因为我们这里第一行只有三个字段,所以只引用到了$3。除此之外另一个这里没有出现的$0,它表示引用当前记录(当前行)的全部内容。

  • 将test的第二行的以点为分段的字段换成以空格为分隔

$ awk -F'.' '{

> if(NR==2){

> print $1 " " $2 " " $3

> }}' test

# 或者

$ awk '

> BEGIN{

> FS="."

> OFS=" " # 如果写为一行,两个动作语句之间应该以";"号分开

> }{

> if(NR==2){

> print $1, $2, $3

> }}' test

说明:这里的-F参数,前面已经介绍过,它是用来预先指定待处理记录的字段分隔符。我们需要注意的是除了指定OFS我们还可以在print语句中直接打印特殊符号如这里的 ,print打印的非变量内容都需要用""一对引号包围起来。上面另一个版本,展示了实现预先指定变量分隔符的另一种方式,即使用BEGIN,就这个表达式指示了,其后的动作将在所有动作之前执行,这里是FS赋值了新的"."点号代替默认的" "空格

注意:首先说明一点,我们在学习和使用awk的时候应该尽可能将其作为一门程序语言来理解,这样将会使你学习起来更容易,所以初学阶段在练习awk时应该尽量按照我那样的方式分多行按照一般程序语言的换行和缩进来输入,而不是全部写到一行(当然这在你熟练了之后是没有任何问题的)。

6.awk常用的内置变量

变量名

说明

FILENAME

当前输入文件名,若有多个文件,则只表示第一个。如果输入是来自标准输入,则为空字符串

$0

当前记录的内容

$N

N表示字段号,最大值为NF变量的值

FS

字段分隔符,由正则表达式表示,默认为" "空格

RS

输入记录分隔符,默认为" ",即一行为一个记录

NF

当前记录字段数

NR

已经读入的记录数

FNR

当前输入文件的记录数,请注意它与NR的区别

OFS

输出字段分隔符,默认为" "空格

ORS

输出记录分隔符,默认为" "

关于awk的内容本课程将只会包含这些内容,如果你想了解更多,请期待后续课程,或者参看一下链接内容:

作业

1、练习其他几个命令动作的使用。

  • 练习1: 结合正则表达式做更多练习。
  • 练习2: 参考下面的链接,掌握 sed 处理文本的基本原理,理解 pattern space 和 hold space 概念。
  • 练习3: 基于 pattern space 和 hold space 实现将一个文本倒序输出和交换奇数行和偶数行。

2、一个在线游戏,当然我们主要目的是学习,这个游戏也是有寓教于乐的性质,让你快速学会vim的基础操作:

vim大冒险

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第14张

【第十二课】

Linux 下软件安装

实验介绍

介绍 Ubuntu 下软件安装的几种方式,及 apt,dpkg 工具的使用。

一、Linux 上的软件安装

通常 Linux 上的软件安装主要有三种方式:

  • 在线安装
  • 从磁盘安装deb软件包
  • 从二进制软件包安装
  • 从源代码编译安装

这几种安装方式各有优劣,而大多数软件包会采用多种方式发布软件,所以我们常常需要全部掌握这几种软件安装方式,以便适应各种环境。下面将介绍前三种安装方式,从源码编译安装你将在 Linux 程序设计中学习到。

二、在线安装

试想一下,平时我们在使用 Windows 的时候,想要安装一个软件,我们需要在网上去下载对应软件的安装包,接着安装的时候就是不断的去点击下一步,这些流程想必大家已经经历的无数回了,但是在 Linux 下,一个命令加回车,等待一下,软件就安装好了,这就是方便的在线安装软件的方式。在学习这种安装方式之前有一点需要说明的是,在不同的linux发行版上面在线安装方式会有一些差异包括使用的命令及它们的包管理工具,因为我们的开发环境是基于ubuntu的,所以这里我们涉及的在线安装方式将只适用于ubuntu发行版,或其它基于ubuntu的发行版如国内的ubuntukylin(优麒麟)ubuntu又是基于debian的发行版,它使用的是debian的包管理工具dpkg,所以一些操作也适用与debian。而在其它一些采用其它包管理工具的发行版如redhatcentos,fedora等将不适用(redhatcentos使用rpm)

1. 先体验一下

比如我们想安装一个软件,名字叫做w3m(w3m是一个命令行的简易网页浏览器),那么输入如下命令:

$ sudo apt-get install w3m

这样的操作你应该在前面的章节中看到过很多次了,它就表示将会安装一个软件包名为w3m的软件

我们来看看命令执行后的效果:

$ w3m www.shiyanlou.com/faq

注意:如果你在安装一个软件之后,无法立即使用Tab键补全这可命令,你可以尝试先执行source ~/.zshrc,然后你就可以使用补全操作。

2. apt 包管理工具介绍

APT是Advance Packaging Tool(高级包装工具)的缩写,是Debian及其派生发行版的软件包管理器,APT可以自动下载,配置,安装二进制或者源代码格式的软件包,因此简化了Unix系统上管理软件的过程。APT最早被设计成dpkg的前端,用来处理deb格式的软件包。现在经过APT-RPM组织修改,APT已经可以安装在支持RPM的系统管理RPM包。这个包管理器包含以apt-开头的的多个工具,如apt-getapt-cacheapt-cdrom等,在Debian系列的发行版中使用。

当你在执行安装操作时,首先apt-get工具会在本地的一个数据库中搜索关于w3m软件的相关信息,并根据这些信息在相关的服务器上下载软件安装,这里大家可能会一个疑问:既然是在线安装软件,为啥会在本地的数据库中搜索?要解释这个问题就得提到几个名词了:

  • 软件源镜像服务器
  • 软件源

我们需要定期从服务器上下载一个软件包列表,使用sudo apt-get update命令来保持本地的软件包列表是最新的(有时你也需要手动执行这个操作,比如更换了软件源),而这个表里会有软件依赖信息的记录,对于软件依赖,我举个例子:我们安装w3m软件的时候,而这个软件需要libgc1c2这个软件包才能正常工作,这个时候apt-get在安装软件的时候会一并替我们安装了,以保证w3m能正常的工作。

3.apt-get

apt-get使用各用于处理apt包的公用程序集,我们可以用它来在线安装、卸载和升级软件包等,下面列出一些apt-get包含的常用的一些工具:

工具

说明

install

其后加上软件包名,用于安装一个软件包

update

从软件源镜像服务器上下载/更新用于更新本地软件源的软件包列表

upgrade

升级本地可更新的全部软件包,但存在依赖问题时将不会升级,通常会在更新之前执行一次update

dist-upgrade

解决依赖关系并升级(存在一定危险性)

remove

移除已安装的软件包,包括与被移除软件包有依赖关系的软件包,但不包含软件包的配置文件

autoremove

移除之前被其他软件包依赖,但现在不再被使用的软件包

purge

与remove相同,但会完全移除软件包,包含其配置文件

clean

移除下载到本地的已经安装的软件包,默认保存在/var/cache/apt/archives/

autoclean

移除已安装的软件的旧版本软件包

下面是一些apt-get常用的参数:

参数

说明

-y

自动回应是否安装软件包的选项,在一些自动化安装脚本中使用这个参数将十分有用

-s

模拟安装

-q

静默安装方式,指定多个q或者-q=#,#表示数字,用于设定静默级别,这在你不想要在安装软件包时屏幕输出过多时很有用

-f

修复损坏的依赖关系

-d

只下载不安装

--reinstall

重新安装已经安装但可能存在问题的软件包

--install-suggests

同时安装APT给出的建议安装的软件包

4.安装软件包

关于安装,如前面演示的一样你只需要执行apt-get install <软件包名>即可,除了这一点,你还应该掌握的是如何重新安装软件包。 很多时候我们需要重新安装一个软件包,比如你的系统被破坏,或者一些错误的配置导致软件无法正常工作。

你可以使用如下方式重新安装:

$ sudo apt-get --reinstall install w3m

另一个你需要掌握的是,如何在不知道软件包完整名的时候进行安装。通常我们是使用Tab键补全软件包名,后面会介绍更好的方法来搜索软件包。有时候你需要同时安装多个软件包,你还可以使用正则表达式匹配软件包名进行批量安装。

5.软件升级

# 更新软件源

$ sudo apt-get update

# 升级没有依赖问题的软件包

$ sudo apt-get upgrade

# 升级并解决依赖关系

$ sudo apt-get dist-upgrade

6.卸载软件

如果你现在觉得w3m这个软件不合自己的胃口,或者是找到了更好的,你需要卸载它,那么简单!同样是一个命令加回车sudo apt-get remove w3m,系统会有一个确认的操作,之后这个软件便“滚蛋了”。

或者,你可以执行

# 不保留配置文件的移除

$ sudo apt-get purge w3m

# 或者 sudo apt-get --purge remove

# 移除不再需要的被依赖的软件包

$ sudo apt-get autoremove

7.软件搜索

当自己刚知道了一个软件,想下载使用,需要确认软件仓库里面有没有,就需要用到搜索功能了,命令如下:

sudo apt-cache search softname1 softname2 softname3……

apt-cache命令则是针对本地数据进行相关操作的工具,search顾名思义在本地的数据库中寻找有关softname1softname2…… 相关软件的信息。现在我们试试搜索一下之前我们安装的软件w3m,如图:

结果显示了4个w3m相关的软件,并且有相关软件的简介。

关于在线安装的的内容我们就介绍这么多,想了解更多关于APT的内容,你可以参考:

三、使用 dpkg 从本地磁盘安装 deb 软件包

1.dpkg 介绍

dpkg 是 Debian 软件包管理器的基础,它被伊恩·默多克创建于 1993 年。dpkg 与 RPM 十分相似,同样被用于安装、卸载和供给和 .deb 软件包相关的信息。

dpkg 本身是一个底层的工具。上层的工具,像是 APT,被用于从远程获取软件包以及处理复杂的软件包关系。"dpkg"是"Debian Package"的简写。

我们经常可以在网络上简单以deb形式打包的软件包,就需要使用dpkg命令来安装。

dpkg常用参数介绍:

参数

说明

-i

安装指定deb包

-R

后面加上目录名,用于安装该目录下的所有deb安装包

-r

remove,移除某个已安装的软件包

-I

显示deb包文件的信息

-s

显示已安装软件的信息

-S

搜索已安装的软件包

-L

显示已安装软件包的目录信息

2.使用dpkg安装deb软件包

我们先使用apt-get加上-d参数只下载不安装,下载emacs编辑器的deb包,下载完成后,我们可以查看/var/cache/apt/archives/目录下的内容,如下图:

然后我们将第一个deb拷贝到home目录下,并使用dpkg安装

$ cp /var/cache/apt/archives/emacs24_24.3+1-4ubuntu1_amd64.deb ~

# 安装之前参看deb包的信息

$ sudo dpkg -I emacs24_24.3+1-4ubuntu1_amd64.deb

如你所见,这个包还额外依赖了一些软件包,这意味着,如果主机目前没有这些被依赖的软件包,直接使用dpkg安装可能会存在一些问题,因为dpkg并不能为你解决依赖关系。

# 使用dpkg安装

$ sudo dpkg -i emacs24_24.3+1-4ubuntu1_amd64.deb

跟前面预料的一样,这里你可能出现了一些错误:

我们将如何解决这个错误了,这就要用到apt-get了,使用它的-f参数了,修复依赖关系的安装

$ sudo apt-get -f install

没有任何错误,这样我们就安装成功了,然后你可以运行emacs程序

3.查看已安装软件包的安装目录

如果你依然在纠结到底linux将软件安装到了什么地方,那么很幸运你将可以通过dpkg找到答案

使用dpkg -L查看deb包目录信息

$ sudo dpkg -L emacs

dpkg还有一些其他的参数,这里将作为练习题由你自己来学习

四、从二进制包安装

二进制包的安装比较简单,我们需要做的只是将从网络上下载的二进制包解压后放到合适的目录,然后将包含可执行的主程序文件的目录添加进PATH环境变量即可,如果你不知道该放到什么位置,请重新复习第四节关于 Linux 目录结构的内容。

作业

这一节是本课程的最后一节,所以这里我们给大家介绍一个很有趣的命令。

安装:

$ sudo apt-get install bb

(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)第15张

【遇到的问题】1.软件无法下载

【解决的办法】1.未解决(根据提示尝试两种方法,都出现包无法下载的问题。关闭虚拟环境重开也无法下载)

免责声明:文章转载自《(20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ThreadLoacl的反思Windows7旗舰版磁盘分区详解—附分区步骤截图下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

linux 下dd命令直接清除分区表(不用再fdisk一个一个的删除啦)

分区表是硬盘的分区信息,要删除一个硬盘的所有分区表很麻烦的,需要fdisk一个一个的删除,其实dd命令可直接清除分区信息,当然,这也是linux给root用户留下的作死方法之一。dd 命令主要参数如下if= in file 输入文件,linux下文件的概念应用范围相当广,通常是普通光盘镜像文件或者块设备of= out file 输出文件,通常是普通光盘镜像...

linux下卸载apache方法小结

方法一 代码如下: 1.root@server ~]# rpm -qa|grep httpdhttpd-2.2.3-11.el5_2.centos.4httpd-manual-2.2.3-11.el5_2.centos.4 说明:rpm –qa | grep httpd命令是为了把httpd相关的包都列出来, 我上面的例子是Linux默认安装apache...

MySQL快速回顾:高级查询操作

8.1 排序数据 检索出的数据并不是以纯粹的随机顺序显示的。如果不排序,数据一般将以它在底层表中出现的顺序显示。这可以是数据最初添加到表中的顺序。但是,如果数据后来进行过更新或删除,则此顺序将会受到MySQL重用回收存储空间的影响。因此,如果不明确控制的话,不能依赖该排序顺序。 关系数据库设计理论认为,如果不明确规定排序顺序,则不应该假定检索出的数据的顺序...

Ubuntu上交叉编译valgrind for Android 4.0.4的过程与注意事项

编译环境:Ubuntu x86_64(Linux root 2.6.32-45-generic #101-Ubuntu SMP Mon Dec 3 15:39:38 UTC 2012 x86_64 GNU/Linux) 运行环境:Android 4.0.4 (Linux kernel 3.0.21 OMAP4460) 一、下载NDK9和valgrind...

Git Windows客户端保存用户名和密码

解决Git Windows客户端保存用户名和密码的方法,至于为什么,就不想说了。 1. 添加一个HOME环境变量,值为%USERPROFILE% 2. 开始菜单中,点击“运行”,输入“%Home%”并打开目录,并新建“_netrc”文件 3. _netrc文件中输入以下相关内容并保存: machine git.cnblogs.com login cnbl...

审计基础-PHP命令执行

1. 命令执行 1.1 程序执行函数 程序执行函数 这些函数和 执行运算符 是紧密关联的。 因此,当运行在 安全模式 时,你必须考虑 safe_mode_exec_dir指示 exec PHP 457 exec — 执行一个外部程序 exec ( string $command ) : string 返回命令执行结果的最后一行内容,实际不echo出来的话回...