20135323符运锦---信息安全系统设计基础第一周学习总结
学习计时:共15小时
读书:1小时
代码:8小时
作业:4小时
博客:2小时
一、学习目标
2. Linux 基础入门:https://www.shiyanlou.com/courses/1
3. Linux命令:en cn
三、学习任务
1. 重点学习 cheat/find/locate/grep/man/whereis/which/apt-get
查找帮助文档、各种示例多多练习,这几个命令会贯穿我们整个学习的学习,掌握这几个命令就可以很好学习其他命令了。
2. 这学期需要掌握的命令有ac,apt-get,bzip2,cat,chgrp,chmod,chown,clear,compress,cp,dd,df,diff,du,dump,evn,find,finger,free,grep,gzip,head,kill,less,ln,locate,l,gout,ls,man,mkdir,more,mount,mt,mv,netstat,nslookup,od,passwd,patch,ps,pstop,pwd,rm,shell,sort,ssh,stty,tail,tar,telnet,touch,tree,uname,unzip,vi,vim,whereis,which,who,write等
3. 测试示例:
- 请在虚拟机中安装DDD软件(其他软件)
- 请演示怎么判断DDD软件能不能安装
- 请查找系统中50M以上的文件
- 请查找系统中两天前修改过的且小于5M的文件
- 请问如何查找操作系统的信息
- 请查找当前目录下所有*.c文件中哪个文件中包含main函数
- 请建立一个目录,里面建立两个子文目录,如何一条命令删除三个目录?
- 如何把一个目录及子目录拷贝到自己的主目录
四、后续学习预告
![](https://images2015.cnblogs.com/blog/745401/201509/745401-20150920133302633-479112140.png)
操作系统始于二十世纪 50 年代,当时的操作系统能运行批处理程序。批处理程序不需要用户的交互,它从文件或者穿孔卡片读取数据,然后输出到另外一个文件或者打印机。
二十世纪六十年代初,交互式操作系统开始流行。它不仅仅可以交互,还能使多个用户从不同的终端同时操作主机。这样的操作系统被称作分时操作系统,它的出现对批处理操作系统是个极大的挑战。许多人尝试开发分时操作系统, 其中包括一些大学的研究项目和商业项目。当时有一个项目叫做" Multics ",它的技术在当时很创新。" Multics "项目的开发并不顺利。它花费了远超过预计的时间来完成,却没有在操作系统市场上占到多少份额。而参加该项目的一个开发团体-贝尔实验室退出了这个项目。他们在退出后开发了他们自己的一个操作系统—— UNIX。
UNIX 最初免费发布并因此在大学里受到欢迎。后来,UNIX 实现了 TCP/IP 协议栈,成为了早期工作站的操作系统的一个流行选择。
1990年,UNIX 在服务器市场尤其是大学校园成为主流操作系统,许多校园都有 UNIX 主机,当然还包括一些研究它的计算机系的学生。这些学生都渴望能在自己的电脑上运行 UNIX 。不幸的是,从那时候开始,UNIX 开始变得商业化,它的价格也变得非常昂贵。而唯一低廉的选择就是 MINIX ,这是一个功能有限的类似 UNIX 的操作系统,作者 Andrew Tanebaum 开发它的目的是用于教学。
1991 年 10 月,Linus Torvalds(Linux 之父)在赫尔辛基大学接触 UNIX ,他希望能在自己的电脑上运行一个类似的操作系统。可是 UNIX 的商业版本非常昂贵,于是他从 MINIX 开始入手,计划开发一个比 MINIX 性能更好的操作系统。很快他就开始了自己的开发工作。他第一次发行的版本很快吸引了一些黑客。尽管最初的 Linux 并没有多少用处,但由于一些黑客的加入使它很快就具有了许多吸引人的特性,甚至一些对操作系统开发不感兴趣的人也开始关注它。
Linux 本身只是操作系统的内核。内核是使其他程序能够运行的基础。它实现了多任务和硬件管理,用户或者系统管理员交互运行的所有程序实际上都运行在内核之上。其中有些程序是必需的,比如说,命令行解释器(shell),它用于用户交互和编写 shell 脚本(.bat文件)。 Linus没有自己去开发这些应用程序,而是使用已有的自由软件。这减少了搭建开发环境而所需花费的工作量。实际上,他经常改写内核,使得那些程序能更容易在 Linux 上运行。许多重要的软件,包括 C 编译器,都来自于自由软件基金 GNU 项目。GNU 项目开始于 1984 年,目的是为了开发一个完全类似于 UNIX 的免费操作系统。为了表扬 GNU 对 Linux 的贡献,许多人把 Linux 称为GNU/Linux(GNU 有自己的内核)。
1992-1993 年,Linux 内核具备了挑战 UNIX 的所有本质特性,包括 TCP/IP 网络,图形界面系统(X window),Linux 同样也吸引了许多行业的关注。一些小的公司开发和发行Linux,有几十个 Linux 用户社区成立。1994 年,Linux 杂志也开始发行。
Linux 内核 1.0 在 1994 年三月发布,内核的发布要经历许多开发周期,直至到达一个稳定的版本。
下面列举一下 Linux 诞生大事件:
-
1965 年,Bell 实验室、MIT、GE(通用电气公司)准备开发 Multics 系统,为了同时支持 300 个终端访问主机,但是 1969 年失败了;
刚开始并没有鼠标、键盘,输入设备只有卡片机,因此如果要测试某个程序,则需要将读卡纸插入卡片机,如果有错误,还需要重新来过; Multics:Multiplexed Information and Computing Service
-
1969 年,Ken Thompson(C语言之父)利用汇编语言开发了 FIle Server System(Unics,即 UNIX 的原型)
因为汇编语言对于硬件的依赖性,因此只能针对特定硬件; 只是为了移植一款“太空旅游”的游戏;
-
1973 年,Dennis Ritchie 和 Ken Thompson 发明了 C 语言,而后写出了 UNIX 的内核
将 B 语言改成 C 语言,由此产生了 C 语言之父; 90% 的代码是 C 语言写的,10% 的代码用汇编写的,因此移植时只要修改那 10% 的代码即可;
-
1977 年,Berkeley 大学的 Bill Joy 针对他的机器修改 UNIX 源码,称为BSD(Berkeley Software Distribution)
Bill Joy 是 Sun 公司的创始人;
-
1979 年,UNIX 发布 System V,用于个人计算机;
-
1984 年,因为 UNIX 规定:“不能对学生提供源码”,Tanenbaum 老师自己编写兼容于 UNIX 的Minix,用于教学;
-
1984 年,Stallman 开始 GNU(GNU's Not Unix)项目,创办 FSF(Free Software Foundation)基金会;
产品:GCC、Emacs、Bash Shell、GLIBC; 倡导“自由软件”; GNU 的软件缺乏一个开放的平台运行,只能在 UNIX 上运行; 自由软件指用户可以对软件做任何修改,甚至再发行,但是始终要挂着 GPL 的版权; 自由软件是可以卖的,但是不能只卖软件,而是卖服务、手册等;
-
1985 年,为了避免 GNU 开发的自由软件被其他人用作专利软件,因此创建 GPL(General Public License)版权声明;
-
1988 年,MIT 为了开发 GUI,成立了 XFree86 的组织;
-
1991 年,芬兰赫尔辛基大学的研究生 Linus Torvalds 基于 gcc、bash 开发了针对 386 机器的 Linux 内核;
-
1994 年,Torvalds 发布 Linux-v1.0;
-
1996 年,Torvalds 发布 Linux-v2.0,确定了 Linux 的吉祥物:企鹅;
UNIX进化史(UNIX大家族族谱1969-2013)
LINUX与WINDOWS的不同?
1.免费与收费
- 最新正版 Windows8.1 官方售价 ¥888;
- Linux 免费或少许费用。
2.软件与支持
- Windows 平台:数量和质量的优势,不过大部分为收费软件;由微软官方提供重要支持和服务;
- Linux 平台:大都为开源自由软件,用户可以修改定制和再发布,由于基本免费没有资金支持,部分软件质量和体验欠缺;有全球所有的 Linux 开发者和自由软件社区提供支持。
3.安全性
- Windows 平台:三天两头打补丁安装系统安全更新,还是会中病毒木马;
- Linux 平台:要说 Linux 没有安全问题,那当然是不可能的,这一点仁者见仁智者见智,相对来说肯定比 Windows 平台要更加安全,使用 Linux 你也不用装某杀毒,某毒霸。
4.使用习惯
- Windows:普通用户基本都是纯图形界面下操作使用,依靠鼠标和键盘完成一切操作,用户上手容易入门简单;
- Linux:兼具图形界面操作(需要使用带有桌面环境的发行版)和完全的命令行操作,可以只用键盘完成一切操作,新手入门较困难,需要一些学习和指导(这正是我们要做的事情),一旦熟练之后效率极高。
5.可定制性
- Windows:这些年之前算是全封闭的,系统可定制性很差;
- Linux:你想怎么做就怎么做,Windows 能做到得它都能,Windows 做不到的,它也能。
6.应用范畴
或许你之前不知道 Linux ,要知道,你之前在 Windows 使用百度,谷歌,上淘宝,聊 QQ 时,支撑这些软件和服务的,是后台成千上万的 Linux 服务器主机,它们时时刻刻都在进行着忙碌的数据处理和运算,可以说世界上大部分软件和服务都是运行在 Linux 之上的。
7.Windows 没有的
- 稳定的系统
- 安全性和漏洞的快速修补
- 多用户
- 用户和用户组的规划
- 相对较少的系统资源占用
- 可定制裁剪,移植到嵌入式平台(如安卓设备)
- 可选择的多种图形用户界面(如 GNOME,KDE)
8.Linux 没有的
- 没有特定的支持厂商
- 游戏娱乐支持度不足
- 专业软件支持度不足
如何学习?
1.学习心态
-
明确目的:你是要用 Linux 来干什么,搭建服务器,做程序开发,还是日常办公,还是娱乐游戏;
-
面对现实:Linux 大都在命令行下操作,能否接受不用或少用图形界面;
-
是学习 Linux 操作系统本身还是某一个Linux发行版(Ubuntu,CentOS,Fedora,OpenSUSE,Debian,Mint 等等),如果你对发行版的概念或者它们之间的关系不明确的话可以参看Linux 发行版。
2.注重基础,从头开始
(二)基本概念及操作
1.LINUX桌面环境介绍
相对于现在的 Windows 系统,UNIX/Linux 本身是没有图形界面的,我们通常在 Unix/Linux 发行版上看到的图形界面实际都只是运行在 Linux 系统之上的一套软件,类似 Windows95 之前的Windows 的图形界面实则也只是运行在 DOS 环境的一套软件。而 Linux 上的这套软件以前是XFree86,现在则是 xorg(X.Org),而这套软件又是通过 X 窗口系统(X Window System,也常被称为X11或X)实现的,X 本身只是工具包及架构协议,而 xorg 便是 X 架构规范的一个实现体,也就是说它是实现了 X 协议规范的一个提供图形用户界面服务的服务器,就像实现了 http 协议提供 web 服务的 Apache。如果只有服务器也是不能实现一个完整的桌面环境的,当然还需要一个客户端,我们称为 X Client,像如下几个大家熟知也最流行的实现了客户端功能的桌面环境KDE,GNOME,XFCE,LXDE,其中就有你看到的,实验楼目前使用的 XFCE 桌面环境,部分老用户可能可以回想起,实验楼之前使用的环境是 LXDE。这也意味着在 Linux 上你可以自己选择安装不同的桌面环境,甚至可以定制自己的专属桌面。
2.Linux终端
1.Terminal(终端)
通常在我们使用 Linux 时,我们并不是直接与系统打交道,而是通过一个叫做 Shell 的中间程序来完成的,在图形界面下为了实现让我们在一个窗口中完成接受用户输入和显示输出,Linux 系统还提供了一个叫做终端模拟器的程序(Terminal),下面几个比较常见的终端模拟器,例如 gnome-terminal,kconsole,xterm,rxvt,kvt,nxterm 和 eterm,目前我们的实验中的终端程序是 xfce 桌面环境自带的 xfce-terminal。不过要注意的是这里所说的终端(Terminal)和控制台(Console)是有区别的。
终端本质上是对应着 Linux 上的 /dev/tty 设备,Linux 的多用户登陆就是通过不同的 /dev/tty 设备完成的,Linux 默认提供了 6 个纯命令行界面的 “terminal”(准确的说这里应该是 6 个 virtual consoles)来让用户登录,在物理机系统上你可以通过使用[Ctrl]
+[Alt]
+[F1]~[F6]
进行切换,不过在我们的在线实验环境中可能无法切换,因为特殊功能按键会被你主机系统劫持。当你切换到其中一个终端后想要切换回图形界面,你可以按下[Ctrl]
+[Alt]
+[F7]
来完成。
2.Shell
通常在图形界面中对实际体验带来差异的不是上述的不同发行版的各种终端模拟器,而大都是这个 Shell(壳),有壳就有核,这里的核就是指的 UNIX/Linux 内核,Shell 是指“提供给使用者使用界面”的软件(命令解析器),类似于 DOS 下的 command(命令行)和后来的 cmd.exe。普通意义上的 Shell 就是可以接受用户输入命令的程序。它之所以被称作 Shell 是因为它隐藏了操作系统底层的细节。同样的 Unix/Linux 下的图形用户界面 GNOME 和 KDE,有时也被叫做“虚拟 shell”或“图形 shell”。
Unix/Linux 操作系统下的 Shell 既是用户交互的界面,也是控制系统的脚本语言。当然在这点也有别于 Windows 下的命令行,虽然也提供了很简单的控制语句。在Windows 操作系统下,可能有些用户从来都不会直接的使用 Shell,然而在 UNIX 系列操作系统下,Shell 仍然是控制系统启动、X11 启动和很多其他实用工具的脚本解释程序。
在 UNIX/Linux 中比较流行的常见的 Shell 有 bash,zsh,ksh,csh 等等,Ubuntu 终端默认使用的是 bash,默认的桌面环境是 GNOME 或者 Unity(基于 GNOME),但我们的环境中使用的分别是zsh 和 xfce。
3.命令行操作体验
如图,双击桌面上的Xface终端
图标,打开终端,打开终端后会自动运行 Shell 程序,然后我们就可以输入命令让系统来执行了:
1).重要快捷键:
真正学习命令行之前,你先要掌握几个十分有用,必需掌握的小技巧:
[Tab]
使用Tab
键来进行命令补全,Tab
键一般键盘是在字母Q
旁边,这个技巧给你带来的最大的好处就是当你忘记某个命令的全称时你可以只输入它的开头的一部分然后按下Tab
键就可以得到提示或者帮助完成:
当然不止补全命令,补全目录,补全命令参数都是没问题的:
想想你有没有遇到这种情况,当你在 Linux 命令行中无意输入了一个不知道的命令,或者错误的使用了一个命令,导致在终端里出现了你无法预料的情况,比如,只有光标在闪烁无法继续输入命令,或者不停地在输出一大堆你不想要的结果。你想要立即停止并恢复到你可控的状态,那该怎么办呢。这时候你就可以使用Ctrl+c
键来强行终止当前程序(你可以放心它并不会使终端退出)。
find /
显然这不是你想的结果,可以使用Ctrl+c
结束。
虽然这个按着很方便,但不要随便按,因为有时候当你看到终端没有任何反应或提示,也不能接受你的输入,可能只是运行的程序需要你耐心的等一下,你就不要急着Ctrl+c
了。
其他一些常用快捷键
键
作用
Ctrl+d
键盘输入结束或退出终端
Ctrl+s
暂定当前程序,暂停后按下任意键恢复运行
Ctrl+z
将当前程序放到后台运行,恢复到前台为命令fg
Ctrl+a
将光标移至输入行头,相当于Home键
Ctrl+e
将光标移至输入行末,相当于End键
Ctrl+k
删除从光标所在位置到行末
Alt+Backspace
向前删除一个单词
Shift+PgUp
将终端显示向上滚动
Shift+PgDn
将终端显示向下滚动
2).学会利用历史输入命令
很简单,你可以使用键盘上的方向上
键,恢复你之前输入过的命令,你一试便知。
3).学会使用通配符
通配符是一种特殊语句,主要有星号(*)和问号(?),用来对对字符串进行模糊匹配(比如文件名,参数名)。当查找文件夹时,可以使用它来代替一个或多个真正字符;当不知道真正字符或者懒得输入完整名字时,常常使用通配符代替一个或多个真正的字符。
终端里面输入的通配符是由 Shell 处理的,不是由所涉及到命令语句处理的,它只会出现在命令的“参数值”里(它不用在 命令名称里, 命令不记得,那就用Tab
补全)。当 Shell 在“参数值”中遇到了通配符时,Shell 会将其当作路径或文件名去在磁盘上搜寻可能的匹配:若符合要求的匹配存在,则进行代换(路径扩展);否则就将该通配符作为一个普通字符传递给“命令”,然后再由命令进行处理。总之,通配符 实际上就是一种 Shell 实现的路径扩展功能。在 通配符被处理后, Shell 会先完成该命令的重组,然后再继续处理重组后的命令,直至执行该命令。
先使用 touch 命令创建 2 个文件,后缀都为 txt:
可以给文件随意命名,假如过了很长时间,你已经忘了这两个文件的文件名,现在你想在你大堆其他文件中找到这两个文本文件,就可以使用通配符:
在创建文件的时候,如果需要一次性创建多个文件,比如:“love_1_linux.txt,love_2_linux.txt,... love_10_linux.txt”。在 Linux 中十分方便:
Shell 常用通配符:
字符 |
含义 |
* |
匹配 0 或多个字符 |
? |
匹配任意一个字符 |
[list] |
匹配 list 中的任意单一字符 |
[!list] |
匹配 除list 中的任意单一字符以外的字符 |
[c1-c2] |
匹配 c1-c2 中的任意单一字符 如:[0-9] [a-z] |
{string1,string2,...} |
匹配 sring1 或 string2 (或更多)其一字符串 |
{c2..c2} |
匹配 c1-c2 中全部字符 如{1..10}
|
4).学会在命令行中获取帮助
在 Linux 环境中,如果你遇到困难,可以使用man
命令,它是Manual page
的缩写。
Manual pages 是在 UNIX 或类 UNIX 操作系统在线软件文档的一种普遍的形式。 内容包括计算机程序(包括库和系统调用),正式的标准和惯例,甚至是抽象的概念。用户可以通过执行 man 命令调用手册页。
通常情况下,man 手册里面的内容都是英文的,这就要求你有一定的英文基础。man 手册的内容很多,涉及了 Linux 使用过程中的方方面面,为了便于查找,是做了分册(分区段)处理的,在Research UNIX、BSD、OS X 和 Linux 中,手册通常被分为8个区段,安排如下:
区段 | 说明 |
---|---|
1 | 一般命令 |
2 | 系统调用 |
3 | 库函数,涵盖了C标准函数库 |
4 | 特殊文件(通常是/dev中的设备)和驱动程序 |
5 | 文件格式和约定 |
6 | 游戏和屏保 |
7 | 杂项 |
8 | 系统管理命令和守护进程 |
要查看相应区段的内容,就在 man 后面加上相应区段的数字即可,如:
$ man 3 printf
所有的手册页遵循一个常见的布局,其为通过简单的 ASCII 文本展示而优化,而这种情况下可能没有任何形式的高亮或字体控制。一般包括以下部分内容:
NAME(名称)
该命令或函数的名称,接着是一行简介。
SYNOPSIS(概要)
对于命令,正式的描述它如何运行,以及需要什么样的命令行参数。对于函数,介绍函数所需的参数,以及哪个头文件包含该函数的定义。
DESCRIPTION(说明)
命令或函数功能的文本描述。
EXAMPLES(示例)
常用的一些示例。
SEE ALSO(参见)
相关命令或函数的列表。
也可能存在其他部分内容,但这些部分没有得到跨手册页的标准化。常见的例子包括:OPTIONS(选项),EXIT STATUS(退出状态),ENVIRONMENT(环境),BUGS(程序漏洞),FILES(文件),AUTHOR(作者),REPORTING BUGS(已知漏洞),HISTORY(历史)和COPYRIGHT(版权)。
通常 man 手册中的内容很多,你可能不太容易找到你想要的结果,不过幸运的是你可以在 man 中使用搜索,/<你要搜索的关键字>
,查找到后你可以使用n
键切换到下一个关键字所在处,shift+n
为上一个关键字所在处。使用Space
(空格键)翻页,Enter
(回车键)向下滚动一行,或者使用j
,k
(vim编辑器的移动键)进行向前向后滚动一行。按下h
键为显示使用帮助(因为man使用less作为阅读器,实为less
工具的帮助),按下q
退出。
想要获得更详细的帮助,你还可以使用info
命令,不过通常使用man
就足够了。如果你知道某个命令的作用,只是想快速查看一些它的某个具体参数的作用,那么你可以使用--help
参数,大部分命令都会带有这个参数,如:
$ ls --help
作业:
你可以先使用如下命令安装:
$ sudo apt-get update;sudo apt-get install sysvbanner
然后:
$ banner shiyanlou
或者你觉得这字体不好看,那么你还可以使用默认已经安装的一个命令printerbanner
:
$ printerbanner -w 50 A
'-w'参数指定打印宽度,因为我们的环境在屏幕中显示比较小,必须要加上宽度限制。
![](https://images2015.cnblogs.com/blog/745401/201509/745401-20150920150738445-1528939875.png)
![](https://images2015.cnblogs.com/blog/745401/201509/745401-20150920150742711-925095270.png)
![](https://images2015.cnblogs.com/blog/745401/201509/745401-20150920150746664-236386348.png)
![](https://images2015.cnblogs.com/blog/745401/201509/745401-20150920150751836-81499476.png)
![](https://images2015.cnblogs.com/blog/745401/201509/745401-20150920150757820-721813890.png)
(三)用户及文件权限管理
用户及文件权限管理
输入的第一列表示打开当前伪终端的用户的用户名(要查看当前登录用户的用户名,去掉空格直接使用whoami
即可),第二列的 pts/0
中 pts
表示伪终端,所谓伪是相对于 /dev/tty
设备而言的,还记得上一节讲终端时的那七个使用[Ctrl]
+[Alt]
+[F1]~[F7]
进行切换的 /dev/tty
设备么,这是“真终端”,伪终端就是当你在图形用户界面使用 /dev/tty7
时每打开一个终端就会产生一个伪终端, pts/0
后面那个数字就表示打开的伪终端序号,你可以尝试再打开一个终端,然后在里面输入who am i
,看第二列是不是就变成 pts/1
了,第三列则表示当前伪终端的启动时间。
who
命令其它常用参数
参数 | 说明 |
---|---|
-a |
打印能打印的全部 |
-d |
打印死掉的进程 |
-m |
同am i ,mom likes |
-q |
打印当前登录用户数及用户名 |
-u |
打印当前登录用户登录信息 |
-r |
打印运行等级 |
2.创建用户
在 Linux 系统里, root
账户拥有整个系统至高无上的权利,比如 新建/添加 用户。
root 权限,系统权限的一种,与 SYSTEM 权限可以理解成一个概念,但高于 Administrator 权限,root 是 Linux 和 UNIX 系统中的超级管理员用户帐户,该帐户拥有整个系统至高无上的权力,所有对象他都可以操作,所以很多黑客在入侵系统的时候,都要把权限提升到 root 权限,用 Windows 的方法理解也就是将自己的非法帐户添加到 Administrators 用户组。更比如安卓操作系统中(基于 Linux 内核)获得 root 权限之后就意味着已经获得了手机的最高权限,这时候你可以对手机中的任何文件(包括系统文件)执行所有增、删、改、查的操作。
我们一般登录系统时都是以普通账户的身份登录的,要创建用户需要 root 权限,这里就要用到 sudo
这个命令了。不过使用这个命令有两个大前提,一是你要知道当前登录用户的密码,二是当前用户必须在sudo
用户组。shiyanlou 用户的密码就是 “shiyanlou” ,它同时也属于 sudo 用户组(稍后会介绍如何查看和添加用户组)。现在我们新建一个用户:
3.用户组
在 Linux 里面每个用户都有一个归属(用户组),用户组简单地理解就是一组用户的集合,它们共享一些资源和权限,同时拥有私有资源,就跟家的形式差不多,你的兄弟姐妹(不同的用户)属于同一个家(用户组),你们可以共同拥有这个家(共享资源),爸妈对待你们都一样(共享权限),你偶尔写写日记,其他人未经允许不能查看(私有资源和权限)。当然一个用户是可以属于多个用户组的,正如你既属于家庭,又属于学校或公司。
方法一:使用groups命令
冒号之前表示用户,后面表示该用户所属的用户组
方法二:查看/etc/group
文件
这里 cat
命令用于读取指定文件的内容并打印到终端输出,后面会详细讲它的使用。 | sort
表示将读取的文本进行一个字典排序再输出,然后你将看到如下一堆输出,你可以在最下面看到 shiyanlou 的用户组信息:
etc/group
文件格式说明
/etc/group 的内容包括用户组(Group)、用户组口令、GID 及该用户组所包含的用户(User),每个用户组一条记录。格式如下:
group_name:password:GID:user_list
你看到上面的 password 字段为一个 'x' 并不是说密码就是它,只是表示密码不可见而已。
将其它用户加入 sudo 用户组
默认情况下新创建的用户是不具有 root 权限的,也不在 sudo 用户组,可以让其加入sudo用户组从而获取 root 权限。
$ su -l lilei
$ sudo ls
会提示 lilei 不在 sudoers 文件中,意思就是 lilei 不在 sudo 用户组中,至于 sudoers 文件(/etc/sudoers)你现在最好不要动它,操作不慎会导致比较麻烦的后果。
使用 usermod
命令可以为用户添加用户组,同样使用该命令你必需有 root 权限,你可以直接使用 root 用户为其它用户添加用户组,或者用其它已经在 sudo 用户组的用户使用 sudo 命令获取权限来执行该命令
这里我用 shiyanlou 用户执行 sudo 命令将 lilei 添加到 sudo 用户组,让它也可以使用 sudo 命令获得 root 权限
$ su shiyanlou
$ groups lilei
$ sudo usermod -G sudo lilei
$ groups lilei
然后你再切换会 lilei 用户,现在就可以使用 sudo 获取 root 权限了。
4.删除用户
Linux 文件权限
1.查看文件权限
我们之前已经很多次用到 ls
命令了,如你所见,我们用它来列出并显示当前目录下的文件,当然这是在不带任何参数的情况下,它能做的当然不止这么多,现在我们就要用它来查看文件权限。
- 文件类型
关于文件类型,这里有一点你必需时刻牢记Linux 里面一切皆文件,正因为这一点才有了设备文件( /dev
目录下有各种设备文件,大都跟具体的硬件设备相关)这一说,还有 socket
(网络套接字,具体是什么,感兴趣的用户可以自己去了解或期待实验楼的后续相关课程),和 pipe
(管道,这个东西很重要,我们以后将会讨论到,这里你先知道有它的存在即可)。软链接文件,链接文件是分为两种的,另一种当然是“硬链接”(硬链接不常用,具体内容不作为本课程讨论重点,而软链接等同于 Windows 上的快捷方式,你记住这一点就够了)
- 文件权限
读权限,表示你可以使用 cat <file name>
之类的命令来读取某个文件的内容;写权限,表示你可以编辑和修改某个文件; 执行权限,通常指可以运行的二进制程序文件或者脚本文件,如同 Windows 上的 'exe' 后缀的文件,不过 Linux 上不是通过文件后缀名来区分文件的类型。你需要注意的一点是,一个目录要同时具有读权限和执行权限才可以打开,而一个目录要有写权限才允许在其中创建其它文件,这是因为目录文件实际保存着该目录里面的文件的列表等信息
所有者权限,这一点相信你应该明白了,至于所属用户组权限,是指你所在的用户组中的所有其它用户对于该文件的权限,比如,你有一个艾派德,那么这个用户组权限就决定了你的兄弟姐妹有没有权限使用它破坏它和占有它。
- 链接数
链接到该文件所在的 inode 结点的文件名数目(关于这个概念涉及到 Linux 文件系统的相关概念知识,不在本课程的讨论范围,感兴趣的用户可以自己去了解)。
- 文件大小
以 inode 结点大小为单位来表示的文件大小,你可以给 ls 加上
-lh
参数来更直观的查看文件的大小。
- 显示除了 '.'(当前目录),'..' 上一级目录之外的所有包含隐藏文件(Linux 下以 '.' 开头的文件为隐藏文件)
2.变更文件所
3.修改文件权限
如果你有一个自己的文件不想被其他用户读、写、执行,那么就需要对文件的权限做修改,这里有两种方式:
- 方式一:二进制数字表示
- 方式二:加减赋值操作
作业
(四)Linux 目录结构及文件基本操作
Linux 目录结构
在讲 Linux 目录结构之前,你首先要清楚一点东西,那就是 Linux 的目录与 Windows 的目录的区别,或许对于一般操作上的感受来说没有多大不同,但从它们的实现机制来说是完全不同的。
一种不同是体现在目录与存储介质(磁盘,内存,DVD 等)的关系上,以往的 Windows 一直是以存储介质为主的,主要以盘符(C 盘,D 盘...)及分区的来实现文件管理,然后之下才是目录,目录就显得不是那么重要,除系统文件之外的用户文件放在任何地方任何目录也是没有多大关系。所以通常 Windows 在使用一段时间后,磁盘上面的文件目录会显得杂乱无章(少数善于整理的用户除外吧)。然而 UNIX/Linux 恰好相反,UNIX 是以目录为主的,Linux 也继承了这一优良特性。 Linux 是以树形目录结构的形式来构建整个系统的,可以理解为一个用户可操作系统的骨架。虽然本质上无论是目录结构还是操作系统内核都是存储在磁盘上的,但从逻辑上来说 Linux 的磁盘是“挂在”(挂载在)目录上的,每一个目录不仅能使用本地磁盘分区的文件系统,也可以使用网络上的文件系统。举例来说,可以利用网络文件系统(Network File System,NFS)服务器载入某特定目录等。
1.FHS 标准
Linux 的目录结构说复杂很复杂,说简单也很简单。复杂在于,因为系统的正常运行是以目录结构为基础的,对于初学者来说里面大部分目录都不知道其作用,重要与否,特别对于哪些曾近的重度 Windows 用户,他们会纠结很长时间,关于我安装的软件在哪里这类问题。说它简单是因为,它其中大部分目录结构是规定好了(FHS 标准),是死的,当你掌握后,你在里面的一切操作都会变得井然有序。
FHS(英文:Filesystem Hierarchy Standard 中文:文件系统层次结构标准),多数 Linux 版本采用这种文件组织形式,FHS 定义了系统中每个区域的用途、所需要的最小构成的文件和目录同时还给出了例外处理与矛盾处理。
FHS 定义了两层规范,第一层是, / 下面的各个目录应该要放什么文件数据,例如 /etc 应该要放置设置文件,/bin 与 /sbin 则应该要放置可执行文件等等。
第二层则是针对 /usr 及 /var 这两个目录的子目录来定义。例如 /var/log 放置系统登录文件、/usr/share 放置共享数据等等。
关于上面提到的 FHS,这里还有个很重要的内容你一定要明白,FHS 是根据以往无数 Linux 用户和开发者的经验总结出来的,并且会维持更新,FHS 依据文件系统使用的频繁与否以及是否允许用户随意改动(注意,不是不能,学习过程中,不要怕这些),将目录定义为四种交互作用的形态,如下表所示:
2.目录路径
路径
有人可能不明白这路径是指什么,有什么用。顾名思义,路径就是你要去哪儿的路线嘛。如果你想进入某个具体的目录或者想获得某个目录的文件(目录本身也是文件)那就得用路径来找到了。
使用
cd
命令可以切换目录,在 Linux 里面使用.
表示当前目录,..
表示上一级目录(**注意,还记得我们上一节介绍过的,以.
开头的文件都是隐藏文件,所以这两个目录必然也是隐藏的,你可以使用ls -a
命令查看隐藏文件),-
表示上一次所在目录,~
通常表示当前用户的"home"目录。使用pwd
命令可以获取当前所在路径(绝对路径)。
绝对路径
关于绝对路径,简单地说就是以根"/"目录为起点的完整路径,以你所要到的目录为终点,表现形式如:
/usr/local/bin
,表示根目录下的 usr 目录中的 local 目录中的 bin 目录。相对路径
相对路径,也就是相对于你当前的目录的路径,相对路径是以当前目录
.
为起点,以你所要到的目录为终点,表现形式如:usr/local/bin
(这里假设你当前目录为根目录)。你可能注意到,我们表示相对路径实际并没有加上表示当前目录的那个.
,而是直接以目录名开头,因为这个usr
目录为/
目录下的子目录,是可以省略这个.
的(以后会讲到一个类似不能省略的情况);如果是当前目录的上一级目录,则需要使用..
,比如你当前目录为“home”目录,根目录就应该表示为../../
,表示上一级目录("home"目录)的上一级目录("/"目录)。下面我们以你的"home"目录为起点,分别以绝对路径和相对路径的方式进入
/usr/local/bin
目录:
进入一个目录,可以使用绝对路径也可以使用相对路径,那我们应该在什么时候选择正确的方式进入某个目录呢。就是凭直觉嘛,你觉得怎样方便就使用哪一个,而不用特意只使用某一种。比如假设我当前在
/usr/local/bin
目录,我想进入上一级的 local 目录你说是使用cd ..
方便还是cd /usr/local
方便。而如果要进入的是usr
目录,那么cd /usr
,就比cd ../..
方便一点了。Linux 文件的基本操作
1.新建
新建空白文件
使用
touch
命令创建空白文件,关于touch
命令,其主要是来更改已有文件的时间戳的(比如,最近访问时间,最近修改时间),但其在不加任何参数的情况下,只指定一个文件名,则可以创建一个为指定文件名的空白文件(不会覆盖已有同名文件),当然你也可以同时指定该文件的时间戳,更多关于touch
命令的用法,会在下一讲文件搜索中涉及。创建名为 test 的空白文件,因为在其他目录没有权限,所以需要先
cd ~
切换回用户的
2.复制
复制文件
使用
cp
(copy)命令复制一个文件或目录到指定目录。将之前创建的"test"文件复制
3.删除
删除文件
使用
rm
(remove files or directories)命令,删除一个文件或目录:
4.移动文件与文件重命名
移动文件
使用
mv
(move or rename files)命令,移动文件(剪切)。将文件"file1"移动到"Documents"目录mv 源目录文件 目的目录
:批量重命名:rename命令(先使用第二个参数的通配符匹配所有后缀为.txt的文件,然后使用第一个参数提供的正则表达式将匹配的这些文件的.txt后缀替换为.c)
5.查看文件
使用
cat
,tac
和nl
命令查看文件这两个命令都是用来打印文件内容到标准输出(终端),其中
cat
为正序显示,tac
倒序显示。标准输入输出:当我们执行一个 shell 命令行时通常会自动打开三个标准文件,即标准输入文件(stdin),默认对应终端的键盘;标准输出文件(stdout)和标准错误输出文件(stderr),这两个文件都对应被重定向到终端的屏幕,以便我们能直接看到输出内容。进程将从标准输入文件中得到输入数据,将正常输出数据输出到标准输出文件,而将错误信息送到标准错误文件中。
![]()
使用
more
和less
命令分页查看文件如果说上面的 cat 是用来快速查看一个文件内容的,那么这个
more
和less
就是天生用来"阅读"一个文件的内容的,比如说"man"手册内部就是使用的 less 来显示内容。其中more
命令比较简单,只能向一个方向滚动,而"less"为基于"more"和"vi"(一个强大的编辑器,我们有单独的课程来让你学习)开发,功能更强大。less 的使用基本和 more 一致,具体使用请查看 man 手册,这里只介绍 more 命令的使用。使用
head
和tail
命令查看文件这两个命令那些性子比较急的人应该会比较喜欢,因为它们一个是只查看的头几行(默认为10行,不足10行则显示全部)和尾几行。还是拿 passwd 文件举例,比如当我们想要查看最近新增加的用户,那么我们可以查看这个
/etc/passwd
文件,不过我们前面也看到了,这个文件里面一大堆乱糟糟的东西,看起来实在费神啊。这里想到系统新增加一个用户,应该会将用户的信息添加到passwd文件的最后,那么这时候我们就可以使用tail
命令了:
6.查看文件类型
前面我提到过,在 Linux 下面文件的类型不是根据文件后缀来判断的,我们通常使用
file
命令可以查看文件的类型:
7.编辑文件
在 Linux 下面编辑文件通常我们会直接使用专门的命令行编辑器比如(emacs,vim,nano),由于涉及 Linux 上的编辑器的内容比较多,且非常重要,故我们有一门单独的基础课专门介绍这其中一个编辑器(vim)。在这里强烈希望正在学习这门 Linux 基础课的你先在这里暂停一下,先去学习vim 编辑器的使用(至少掌握基本的操作)然后再继续本课程后面的内容,因为后面的内容会假设你已经学会了 vim 编辑器的使用。如果你想更加快速的入门,你可以直接使用 Linux 内部的 vim 学习教程,输入如下命令即可开始:
作业
(五)环境变量与文件查找
环境变量
1.变量
要解释环境变量,得先明白变量是什么,准确的说应该是 Shell 变量,所谓变量就是计算机中用于记录一个值(不一定是数值,也可以是字符或字符串)的符号,而这些符号将用于不同的运算处理中。通常变量与值是一对一的关系,可以通过表达式读取它的值赋值给其它变量,也可以直接指定数值赋值给任意变量。为了便于运算和处理,大部分的编程语言会区分变量的类型,用于分别记录数值、字符或者字符串等等数据类型。Shell 中的变量也基本如此,有不同类型(但不用专门指定类型名),可以参与运算,有作用域限定。
变量的作用域即变量的有效范围(比如一个函数中、一个源文件中或者全局范围),在该范围内只能有一个同名变量。一旦离开则该变量无效,如同不存在这个变量一般。
在 Shell 中如何创建一个变量,如何给变量赋值和如何读取变量的值呢?这部分内容会在bash 脚本编程这门课中详细介绍,这里我简单举例说明一下:
使用
declare
命令创建一个变量名为 tmp 的变量:
$ declare tmp
其实也可以不用 declare 预声明一个变量,直接即用即创建,这里只是告诉你 declare 的作用,这在创建其它指定类型的变量(如数组)时会用到。
使用
=
号赋值运算符为变量 tmp 赋值为 shiyanlou:
$ tmp=shiyanlou
读取变量的值,使用
echo
命令和$
符号($符号用于表示引用一个变量的值,初学者经常会忘记输入):
$ echo $tmp
注意:关于变量名,并不是任何形式的变量名都是可用的,变量名只能是英文字母,数字或者下划线,且不能以数字作为开头。
2.环境变量
简单理解了变量的概念,就很好解释环境变量了,环境变量就是作用域比自定义变量要大,如Shell 的环境变量作用于自身和它的子进程。在所有的 UNIX 和类 UNIX 系统中,每个进程都有其各自的环境变量设置,且默认情况下,当一个进程被创建时,处理创建过程中明确指定的话,它将继承其父进程的绝大部分环境设置。Shell 程序也作为一个进程运行在操作系统之上,而我们在 Shell中运行的大部分命令都将以 Shell 的子进程的方式运行。
命令
说明
set
显示当前 Shell 所有环境变量,包括其内建环境变量(与 Shell 外观等相关),用户自定义变量及导出的环境变量
env
显示与当前用户相关的环境变量,还可以让命令在指定环境中运行
export
显示从 Shell 中导出成环境变量的变量,也能通过它将自定义变量导出为环境变量
3.命令的查找路径与顺序
你可能很早之前就有疑问,我们在 Shell 中输入一个命令,Shell 是怎么知道在哪去找到这个命令然后执行的呢?这是通过环境变量
PATH
来进行搜索的,熟悉 Windows 的用户可能知道 Windows 中的也是有这么一个 PATH 环境变量。这个PATH
里面就保存了Shell中执行的命令的搜索路径。查看
PATH
环境变量的内容:
$ echo $PATH
默认情况下你会看到如下输出:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
如果你还记得我们在 Linux 目录结构那一节的内容,你就应该知道上面这些目录下放的是哪一类文件了。通常这一类目录下放的都是可执行文件,当我们在 Shell 中执行一个命令时,系统就会按照 PATH 中设定的路径按照顺序依次到目录中去查找,如果存在同名的命令,则执行先找到的那个。
下面我们将练习创建一个最简单的可执行 Shell 脚本和一个使用 C 语言创建的"hello world"程序,如果这两部分内容你之前没有学习过,那么你可以进行一个入门学习: C 语言入门教程高级 Bash 脚本编程指南Linux Shell Scripting Tutorial (LSST) v2.0
5.修改和删除已有变量
变量修改
变量的修改有以下几种方式:
变量设置方式
说明
${变量名#匹配字串}
从头向后开始匹配,删除符合匹配字串的最短数据
${变量名##匹配字串}
从头向后开始匹配,删除符合匹配字串的最长数据
${变量名%匹配字串}
从尾向前开始匹配,删除符合匹配字串的最短数据
${变量名%%匹配字串}
从尾向前开始匹配,删除符合匹配字串的最长数据
${变量名/旧的字串/新的字串}
将符合旧字串的第一个字串替换为新的字串
${变量名//旧的字串/新的字串}
将符合旧字串的全部字串替换为新的字串
6.如何让环境变量立即生效
二、搜索文件
与搜索相关的命令常用的有如下几个
whereis
,which
,find
,locate
。你会看到它找到了三个路径,两个可执行文件路径和一个 man 在线帮助文件所在路径,这个搜索很快,因为它并没有从硬盘中依次查找,而是直接从数据库中查询。
whereis
只能搜索二进制文件(-b),man帮助文件(-m)和源代码文件(-s)。如果想要获得更全面的搜索结果可以使用locate
命令。
locate
快而全通过"/var/lib/mlocate/mlocate.db"数据库查找,不过这个数据库也不是实时更新的,系统会使用定时任务每天自动执行
updatedb
命令更新一次,所以有时候你刚添加的文件,它可能会找不到,需要手动执行一次updatedb
命令(在我们的环境中必须先执行一次该命令)。它可以用来查找指定目录下的不同文件类型,如查找 /etc 下所有以 sh 开头的文件:
$ locate /etc/sh
注意,它不只是在 etc 目录下查找并会自动递归子目录进行查找
查找 /usr/share/ 下所有 jpg 文件:
$ locate /usr/share/\*.jpg
注意要添加
*
号前面的反斜杠转义,否则会无法找到如果想只统计数目可以加上
-c
参数,-i
参数可以忽略大小写进行查找,whereis 的-b
,-m
,-s
同样可以是使用。
which
小而精
which
本身是 Shell 内建的一个命令,我们通常使用which
来确定是否安装了某个指定的软件,因为它只从PATH
环境变量指定的路径中去搜索命令:
$ which man
find
精而细
find
应该是这几个命令中最强大的了,它不但可以通过文件类型、文件名进行查找而且可以根据文件的属性(如文件的时间戳,文件的权限等)进行搜索。find
命令强大到,要把它将明白至少需要单独好几节课程才行,我们这里只介绍一些常用的内容。在指定目录下搜索指定文件名的文件:
$ find /etc/ -name interfaces
注意 find 命令的路径是作为第一个参数的, 基本命令格式为 find [path] [option] [action]
与时间相关的命令参数:
参数 说明 -atime
最后访问时间 -ctime
创建时间 -mtime
最后修改时间 下面以
-mtime
参数举例:
-mtime n
: n 为数字,表示为在n天之前的”一天之内“修改过的文件-mtime +n
: 列出在n天之前(不包含n天本身)被修改过的文件-mtime -n
: 列出在n天之前(包含n天本身)被修改过的文件newer file
: file为一个已存在的文件,列出比file还要新的文件名作业
- 作业
(六)文件打包与压缩
文件打包和解压缩
在讲 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包
使用
-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解压文件时我们同样应该注意兼容问题,不过这里我们关心的不再是上面的问题,而是中文编码的问题,通常 Windows 系统上面创建的压缩文件,如果有有包含中文的文档或以中文作为文件名的文件时默认会采用 GBK 或其它编码,而 Linux 上面默认使用的是 UTF-8 编码,如果不加任何处理,直接解压的话可能会出现中文乱码的问题(有时候它会自动帮你处理),为了解决这个问题,我们可以在解压时指定编码类型。
使用
-O
(英文字母,大写o)参数指定编码类型:
unzip -O GBK 中文压缩文件.zip
3.
rar
打包压缩命令
rar
也是 Windows 上常用的一种压缩文件格式,在 Linux 上可以使用rar
和unrar
工具分别创建和解压 rar 压缩包。
- 安装
rar
和unrar
工具:
- 从指定文件或目录创建压缩包或添加文件到压缩包:
上面的命令使用
a
参数添加一个目录~
到一个归档文件中,如果该文件不存在就会自动创建。注意:rar 的命令参数没有
-
,如果加上会报错。
- 从指定压缩包文件中删除某个文件:
$ rar d shiyanlou.rar .zshrc
- 查看不解压文件:
$ 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.gz
-z
*.tar.xz
-J
*tar.bz2
-j
tar 命令的参数很多,不过常用的就是上述这些,需要了解更多你可以查看 man 手册获取更多帮助。
作业
(七)文件系统操作与磁盘管理
简单文件系统操作
1.查看磁盘和目录的容量
使用 df 命令查看磁盘的容量
一般使用情况下,我们更多只是关心第一行的内容也就是环境中的
rootfs
或者物理主机上的/dev/sda2
"rootfs" : (Root File System)它是 Ramfs(Ramfs 是一个非常简单的 Linux 文件系统用于实现磁盘缓存机制作为动态可调整大小的基于 ram 的文件系统)或者 tmpfs 的一个特殊实例,它作为系统启动时内核载入内存之后,在挂载真正的的磁盘之前的一个临时文件系统。通常的主机会在系统启动后用磁盘上的文件系统替换,只是在一些嵌入式系统中会只存在一个 rootfs ,或者像我们目前遇到的情况运行在虚拟环境中共享主机资源的系统也可能会采用这种方式。
物理主机上的 /dev/sda2 是对应着主机硬盘的分区,后面的数字表示分区号,数字前面的字母 a 表示第几块硬盘(也可能是可移动磁盘),你如果主机上有多块硬盘则可能还会出现 /dev/sdb,/dev/sdc 这些磁盘设备都会在 /dev 目录下以文件的存在形式。
接着你还会看到"1k-blocks"这个陌生的东西,它表示以磁盘块大小的方式显示容量,后面为相应的以块大小表示的已用和可用容量,
简单的磁盘管理
下面涉及的命令具有一定的危险性,操作不当可能会丢失你的个人数据,初学者建议在虚拟环境中进行操作
通常情况下,这一小节应该直接将如何挂载卸载磁盘,如何格式化磁盘,如何分区,但如你所见,我们的环境中没东西给你挂,也没东西给你格和分,所以首先我们会先创建一个虚拟磁盘来进行后续的练习操作
1.创建虚拟磁盘
dd 命令简介(部分说明来自dd (Unix) wiki))
dd
命令用于转换和复制文件,不过它的复制不同于cp
。之前提到过关于 Linux 的很重要的一点,一切即文件,在 Linux 上,硬件的设备驱动(如硬盘)和特殊设备文件(如/dev/zero
和/dev/random
)都像普通文件一样,只要在各自的驱动程序中实现了对应的功能,dd 也可以读取自和/或写入到这些文件。这样,dd
也可以用在备份硬件的引导扇区、获取一定数量的随机数据或者空数据等任务中。dd
程序也可以在复制时处理数据,例如转换字节序、或在 ASCII 与 EBCDIC 编码间互换。
dd
的命令行语句与其他的 Linux 程序不同,因为它的命令行选项格式为选项=值
,而不是更标准的--选项 值
或-选项=值
。dd
默认从标准输入中读取,并写入到标准输出中,但可以用选项if
(input file,输入文件)和of
(output file,输出文件)改变。我们先来试试用
dd
命令从标准输入读入用户输入到标准输出或者一个文件:
上述命令从标准输入设备读入用户输入(缺省值,所以可省略)然后输出到 test 文件,
bs
(block size)用于指定块大小(缺省单位为 Byte,也可为其指定如'K','M','G'等单位),count
用于指定块数量。如上图所示,我指定只读取总共 10 个字节的数据,当我输入了“hello shiyanlou”之后加上空格回车总共 16 个字节(一个英文字符占一个字节)内容,显然超过了设定大小。使用和du
和cat
命令看到的写入完成文件实际内容确实只有 10 个字节(那个黑底百分号表示这里没有换行符),而其他的多余输入将被截取并保留在标准输入。前面说到
dd
在拷贝的同时还可以实现数据转换,那下面就举一个简单的例子:将输出的英文字符转换为大写再写入文件:
你可以在
man
文档中查看其他所有转换参数。使用 dd 命令创建虚拟镜像文件
通过上面一小节,你应该掌握了
dd
的基本使用,下面就来使用dd
命令来完成创建虚拟磁盘的第一步。从
/dev/zero
设备创建一个容量为 256M 的空文件:
$ dd if=/dev/zero of=virtual.img bs=1M count=256 $ du -h virtual.img
然后我们要将这个文件格式化(写入文件系统),这里我们要学到一个(准确的说是一组)新的命令来完成这个需求。
使用 mkfs 命令格式化磁盘(我们这里是自己创建的虚拟磁盘镜像)
你可以在命令行输入 mkfs 然后按下
Tab
键,你可以看到很多个以 mkfs 为前缀的命令,这些不同的后缀其实就是表示着不同的文件系统,可以用 mkfs 格式化成的文件系统:可以看到实际 mkfs.ext4 是使用 mke2fs 来完成格式化工作的。mke2fs 的参数很多,不过我们也不会经常格式化磁盘来玩,所以就掌握这基本用法吧,等你有特殊需求时,再查看 man 文档解决。
更多关于文件系统的知识,请查看wiki: 文件系统 ext3,ext4
如果你想想知道 Linux 支持哪些文件系统你可以输入
ls -l /lib/modules/$(uname -r)/kernel/fs
(我们的环境中无法查看)查看。使用 mount 命令挂载磁盘到目录树
用户在 Linux/UNIX 的机器上打开一个文件以前,包含该文件的文件系统必须先进行挂载的动作,此时用户要对该文件系统执行 mount 的指令以进行挂载。通常是使用在 USB 或其他可移除存储设备上,而根目录则需要始终保持挂载的状态。又因为 Linux/UNIX 文件系统可以对应一个文件而不一定要是硬件设备,所以可以挂载一个包含文件系统的文件到目录树。
Linux/UNIX 命令行的 mount 指令是告诉操作系统,对应的文件系统已经准备好,可以使用了,而该文件系统会对应到一个特定的点(称为挂载点)。挂载好的文件、目录、设备以及特殊文件即可提供用户使用。
我们先来使用
mount
来查看下主机已经挂载的文件系统:
$ sudo mount
输出的结果中每一行表示一个设备或虚拟设备,每一行最前面是设备名,然后是 on 后面是挂载点,type 后面表示文件系统类型,再后面是挂载选项(比如可以在挂载时设定以只读方式挂载等等)。
那么我们如何挂载真正的磁盘到目录树呢,
mount
命令的一般格式如下:
不过遗憾的是,由于我们环境的问题(环境中使用的 Linux 内核在编译时没有添加对 Loop device的支持),所以你将无法挂载成功:
另外关于 loop 设备,你可能会有诸多疑问,那么请看下面来自维基百科/dev/loop的说明:
在类 UNIX 系统中,/dev/loop(或称vnd (vnode disk)、lofi(循环文件接口))是一种伪设备,这种设备使得文件可以如同块设备一般被访问。
在使用之前,循环设备必须与现存文件系统上的文件相关联。这种关联将提供给用户一个应用程序接口,接口将允许文件视为块特殊文件(参见设备文件系统)使用。因此,如果文件中包含一个完整的文件系统,那么这个文件就能如同磁盘设备一般被挂载。
这种设备文件经常被用于光盘或是磁盘镜像。通过循环挂载来挂载包含文件系统的文件,便使处在这个文件系统中的文件得以被访问。这些文件将出现在挂载点目录。如果挂载目录中本身有文件,这些文件在挂载后将被禁止使用。
使用 fdisk 为磁盘分区(关于分区的一些概念不清楚的用户请参看主引导记录)
同样因为环境原因中没有物理磁盘,也无法创建虚拟磁盘的原因我们就无法实验练习使用该命令了,下面我将以我的物理主机为例讲解如何为磁盘分区。
# 查看硬盘分区表信息 $ sudo fdisk -l
输出结果中开头显示了我主机上的磁盘的一些信息,包括容量扇区数,扇区大小,I/O 大小等信息。
我们重点开一下中间的分区信息,/dev/sda1,/dev/sda2 为主分区分别安装了 Windows 和 Linux 操作系统,/dev/sda3 为交换分区(可以理解为虚拟内存),/dev/sda4 为扩展分区其中包含 /dev/sda5,/dev/sda6,/dev/sda7,/dev/sda8 四个逻辑分区,因为主机上有几个分区之间有空隙,没有对齐边界扇区,所以分区之间的不是完全连续的。
# 进入磁盘分区模式 $ sudo fdisk virtual.img
在进行操作前我们首先应先规划好我们的分区方案,这里我将在使用 128M(可用 127M 左右)的虚拟磁盘镜像创建一个 30M 的主分区剩余部分为扩展分区包含 2 个大约 45M 的逻辑分区。
操作完成后输入
p
查看结果如下:
最后不要忘记输入
w
写入分区表。使用 losetup 命令建立镜像与回环设备的关联
$ sudo losetup /dev/loop0 virtual.img # 如果提示设备忙你也可以使用其它的回环设备,"ls /dev/loop*"参看所有回环设备 # 解除设备关联 $ sudo losetup -d /dev/loop0
然后再使用
mkfs
格式化各分区(前面我们是格式化整个虚拟磁盘镜像文件或磁盘),不过格式化之前,我们还要为各分区建立虚拟设备的映射,用到kpartx
工具,需要先安装:
$ sudo apt-get install kpartx $ sudo kpart kpartx -av /dev/loop0 # 取消映射 $ sudo kpart kpartx -dv /dev/loop0
接着再是格式化,我们将其全部格式化为 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 # 卸载磁盘分区 $ sudo umount /dev/mapper/loop0p1 $ sudo umount /dev/mapper/loop0p5 $ sudo umount /dev/mapper/loop0p6
作业
(八)命令执行顺序控制与管道
命令执行顺序的控制
1.顺序执行多条命令
通常情况下,我们每次只能在终端输入一条命令,按下回车执行,执行完成后,我们再输入第二条命令,然后再按回车执行…… 你可能会遇到如下使用场景:我需要使用apt-get
安装一个软件,然后安装完成后立即运行安装的软件(或命令工具),又恰巧你的主机才更换的软件源还没有更新软件列表(比如之前我们的环境中,每次重新开始实验就得sudo apt-get update,现在已经没有这个问题了),那么你可能会有如下一系列操作:
命令执行顺序的控制
1.顺序执行多条命令
通常情况下,我们每次只能在终端输入一条命令,按下回车执行,执行完成后,我们再输入第二条命令,然后再按回车执行…… 你可能会遇到如下使用场景:我需要使用apt-get
安装一个软件,然后安装完成后立即运行安装的软件(或命令工具),又恰巧你的主机才更换的软件源还没有更新软件列表(比如之前我们的环境中,每次重新开始实验就得sudo apt-get update,现在已经没有这个问题了),那么你可能会有如下一系列操作:
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个字段分别表示用户名和其家目录
3.grep 命令,在文本中或 stdin 中查找匹配字符串
grep
命令是很强大的,也是相当常用的一个命令,它结合正则表达式可以实现很复杂却很高效的匹配和查找,不过在学习正则表达式之前,这里介绍它简单的使用,而关于正则表达式后面将会有单独一小节介绍到时会再继续学习grep
命令和其他一些命令。
grep
命令的一般形式为:
grep [命令选项]... 用于匹配的表达式 [文件]...
还是先体验一下,我们搜索/home/shiyanlou
目录下所有包含"shiyanlou"的所有文本文件,并显示出现在文本中的行号:
sort 排序命令
这个命令前面我们也是用过多次,功能很简单就是将输入按照一定方式排序,然后再输出,它支持的排序有按字典排序,数字排序,按月份排序,随机排序,反转排序,指定特定字段进行排序等等。
默认为字典排序:
上面的-t
参数用于指定字段的分隔符,这里是以":"作为分隔符;-k 字段号
用于指定对哪一个字段进行排序。这里/etc/passwd
文件的第三个字段为数字,默认情况下是一字典序排序的,如果要按照数字排序就要加上-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
文本处理命令还有很多,下一节将继续介绍一些常用的文本处理的命令。
作业:
(九)简单的文本处理
文本处理命令
1.tr 命令
tr 命令可以用来删除一段文本信息中的某些文字。或者将其进行转换。
使用方式:
tr [option]...SET1 [SET2]
常用的选项有:
选项 | 说明 |
---|---|
-d |
删除和set1匹配的字符,注意不是全词匹配也不是按字符顺序匹配 |
-s |
去除set1指定的在输入文本中连续并重复的字符 |
操作举例:
# 删除 "hello shiyanlou" 中所有的'o','l','h'
$ echo 'hello shiyanlou' | tr -d 'olh'
# 将"hello" 中的ll,去重为一个l
$ echo 'hello' | tr -s 'l'
# 将输入文本,全部转换为大写或小写输出
$ cat /etc/passwd | tr '[:lower:]' '[:upper:]'
# 上面的'[:lower:]' '[:upper:]'你也可以简单的写作'[a-z]' '[A-Z]',当然反过来将大写变小写也是可以的
更多 tr 的使用,你可以使用--help
或者man tr
获得。
2.col 命令
col 命令可以将Tab
换成对等数量的空格建,或反转这个操作。
使用方式:
col [option]
常用的选项有:
选项 | 说明 |
---|---|
-x |
将Tab 转换为空格 |
-h |
将空格转换为Tab (默认选项) |
操作举例:
# 查看 /etc/protocols 中的不可见字符,可以看到很多 ^I ,这其实就是 Tab 转义成可见字符的符号
$ cat -A /etc/protocols
# 使用 col -x 将 /etc/protocols 中的 Tab 转换为空格,然后再使用 cat 查看,你发现 ^I 不见了
$ cat /etc/protocols | col -x | cat -A
3.join命令
学过数据库的用户对这个应该不会陌生,这个命令就是用于将两个文件中包含相同内容的那一行合并在一起。
使用方式:
join [option]... file1 file2
常用的选项有:
选项 | 说明 |
---|---|
-t |
指定分隔符,默认为空格 |
-i |
忽略大小写的差异 |
-1 |
指明第一个文件要用哪个字段来对比,,默认对比第一个字段 |
-2 |
指明第二个文件要用哪个字段来对比,,默认对比第一个字段 |
操作举例:
# 创建两个文件
$ echo '1 hello' > file1
$ echo '1 shiyanlou' > file2
$ join file1 file2
# 将/etc/passwd与/etc/shadow两个文件合并,指定以':'作为分隔符
$ sudo join -t':' /etc/passwd /etc/shadow
# 将/etc/passwd与/etc/group两个文件合并,指定以':'作为分隔符, 分别比对第4和第3个字段
$ sudo join -t':' -1 4 /etc/passwd -2 3 /etc/group
4.paste命令
paste
这个命令与join
命令类似,它是在不对比数据的情况下,简单地将多个文件合并一起,以Tab
隔开。
使用方式:
paste [option] file...
常用的选项有:
选项 | 说明 |
---|---|
-d |
指定合并的分隔符,默认为Tab |
-s |
不合并到一行,每个文件为一行 |
操作举例:
$ echo hello > file1
$ echo shiyanlou > file2
$ echo www.shiyanlou.com > file3
$ paste -d ':' file1 file2 file3
$ paste -s file1 file2 file3
![](https://images2015.cnblogs.com/blog/745401/201509/745401-20150920203058836-1247573813.png)
作业
(十)数据流重定向
1.简单的重定向
在更多了解 Linux 的重定向之前,我们需要先知道一些基本的东西,前面我们已经提到过 Linux 默认提供了三个特殊设备,用于终端的显示和输出,分别为stdin
(标准输入,对应于你在终端的输入),stdout
(标准输出,对应于终端的输出),stderr
(标准错误输出,对应于终端的输出)。
文件描述符 | 设备文件 | 说明 |
---|---|---|
0 |
/dev/stdin |
标准输入 |
1 |
/dev/stdout |
标准输出 |
2 |
/dev/stderr |
标准错误 |
文件描述符:文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于 UNIX、Linux 这样的操作系统。
另外还有一个符号-
,它可以同时作为前一个命令的。
我们可以这样使用这些文件描述符:
默认使用终端的标准输入作为命令的输入和标准输出作为命令的输出
$ cat
(按Ctrl+C退出)
将cat的连续输出(heredoc方式)重定向到一个文件
$ mkdir Documents
$ cat > Documents/test.c\~ <<EOF
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
EOF
将一个文件作为命令的输入,标准输出作为命令的输出
$ cat Documents/test.c\~
将echo命令通过管道传过来的数据作为cat命令的输入,将标准输出作为命令的输出
$ echo 'hi' | cat
将echo命令的输出从默认的标准输出重定向到一个普通文件
$ echo 'hello shiyanlou' > redirect
$ cat redirect
2.标准错误重定向
重定向标准输出到文件,这是一个很实用的操作,另一个很实用的操作是将标准错误重定向,标准输出和标准错误都被指向伪终端的屏幕显示,所以我们经常看到的一个命令的输出通常是同时包含了标准输出和标准错误的结果的。比如下面的操作:
# 使用cat 命令同时读取两个文件,其中一个存在,另一个不存在
$ cat Documents/test.c\~ hello.c
# 你可以看到除了正确输出了前一个文件的内容,还在末尾出现了一条错误信息
# 下面我们将输出重定向到一个文件,根据我们前面的经验,这里将在看不到任何输出了
$ cat Documents/test.c\~ hello.c > somefile
3.使用tee
命令同时重定向到多个文件
经常你可能还有这样的需求,除了将需要将输出重定向到文件之外也需要将信息打印在终端,那么你可以使用tee
命令来实现:
$ echo 'hello shiyanlou' | tee hello
4.永久重定
你应该可以看出我们前面的重定向操作都只是临时性的,即只对当前命令有效,那如何做到“永久”有效呢,比如在一个脚本中,你需要某一部分的命令的输出全部进行重定向,难道要让你在每个命令上面加上临时重定向的操作嘛,当然不需要,我们可以使用exec
命令实现“永久”重定向。exec
命令的作用是使用指定的命令替换当前的 Shell,及使用一个进程替换当前进程,或者指定新的重定向:
# 先开启一个子 Shell
$ zsh
# 使用exec替换当前进程的重定向,将标准输出重定向到一个文件
$ exec 1>somefile
# 后面你执行的命令的输出都将被重定向到文件中,直到你退出当前子shell,或取消exec的重定向(后面将告诉你怎么做)
$ ls
$ exit
$ cat somefile
5.创建输出文件描述符
默认在 Shell 中可以有9个打开的文件描述符,上面我们使用了也是它默认提供的0
,1
,2
号文件描述符,另外我们还可以使用3-8的文件描述符,只是它们默认没有打开而已,你可以使用下面命令查看当前 Shell 进程中打开的文件描述符:
$ cd /dev/fd/;ls -Al
同样使用exec
命令可以创建新的文件描述符:
$ zsh
$ exec 3>somefile
# 先进入目录,再查看,否则你可能不能得到正确的结果,然后再回到上一次的目录
$ cd /dev/fd/;ls -Al;cd -
# 注意下面的命令>与&之间不应该有空格,如果有空格则会出错
$ echo "this is test" >&3
$ cat somefile
$ exit
6.关闭文件描述符
如上面我们打开的3号文件描述符,可以使用如下操作将它关闭:
$ exec 3>&-
$ cd /dev/fd;ls -Al;cd -
7.完全屏蔽命令的输出
在 Linux 中有一个被成为“黑洞”的设备文件,所以导入它的数据都将被“吞噬”。
在类 UNIX 系统中,/dev/null,或称空设备,是一个特殊的设备文件,它通常被用于丢弃不需要的输出流,或作为用于输入流的空文件,这些操作通常由重定向完成。读取它则会立即得到一个EOF。
我们可以利用设个/dev/null
屏蔽命令的输出:
$ cat Documents/test.c\~ nefile 1>/dev/null 2>&1
向上面这样的操作将使你得不到任何输出结果。
8.使用 xargs 分割参数列表
xargs 是一条 UNIX 和类 UNIX 操作系统的常用命令。它的作用是将参数列表转换成小块分段传递给其他命令,以避免参数列表过长的问题。
这个命令在有些时候十分有用,特别是当用来处理产生大量输出结果的命令如 find,locate 和 grep 的结果,详细用法请参看 man 文档。
$ cut -d: -f1 < /etc/passwd | sort | xargs echo
上面这个命令用于将/etc/passwd
文件按:
分割取第一个字段排序后,使用echo
命令生成一个列表。
作业
(十一)正则表达式基础
正则表达式
什么是正则表达式呢?
正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语: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是一个非负整数。匹配确定的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”。 |
. | 匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“(.|\n)”的模式。 |
(pattern) | 匹配pattern并获取这一匹配的子字符串。该子字符串用于向后引用。要匹配圆括号字符,请使用“\(”或“\)”。 |
x|y | 匹配x或y。例如,“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
环境变量。
使用正则表达式
使用基本正则表达式,BRE
- 位置
查找/etc/group
文件中以"shiyanlou"为开头的行
$ grep 'shiyanlou' /etc/group
$ grep '^shiyanlou' /etc/group
- 数量
# 将匹配以'z'开头以'o'结尾的所有字符串
$ echo 'zero\nzo\nzoo' | grep 'z.*o'
# 将匹配以'z'开头以'o'结尾,中间包含一个任意字符的字符串
$ echo 'zero\nzo\nzoo' | grep 'z.o'
# 将匹配以'z'开头,以任意多个'o'结尾的字符串
$ echo 'zero\nzo\nzoo' | grep 'zo*'
注意:其中\n
为换行符
- 选择
# grep默认是区分大小写的,这里将匹配所有的小写字母
$ echo '1234\nabcd' | grep '[a-z]'
# 将匹配所有的数字
$ echo '1234\nabcd' | grep '[0-9]'
# 将匹配所有的数字
$ echo '1234\nabcd' | grep '[[:digit:]]'
# 将匹配所有的小写字母
$ echo '1234\nabcd' | grep '[[:lower:]]'
# 将匹配所有的大写字母
$ echo '1234\nabcd' | grep '[[:upper:]]'
# 将匹配所有的字母和数字,包括0-9,a-z,A-Z
$ echo '1234\nabcd' | grep '[[:alnum:]]'
# 将匹配所有的字母
$ echo '1234\nabcd' | 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\nzo\nzoo' | grep -E 'zo{1}'
# 匹配以"zo"开头的所有单词
$ echo 'zero\nzo\nzoo' | grep -E 'zo{1,}'
注意:推荐掌握
{n,m}
即可,+
,?
,*
,这几个不太直观,且容易弄混淆。
- 选择
# 匹配"www.shiyanlou.com"和"www.google.com"
$ echo 'www.shiyanlou.com\nwww.baidu.com\nwww.google.com' | grep -E 'www\.(shiyanlou|google)\.com'
# 或者匹配不包含"baidu"的内容
$ echo 'www.shiyanlou.com\nwww.baidu.com\nwww.google.com' | grep -Ev 'www\.baidu\.com'
注意:因为
.
号有特殊含义,所以需要转义。三、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'
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
会默认匹配输入文本的全部内容,然后在"{}"花括号中执行动作,即
- 将test的第一行的每个字段单独显示为一行
$ awk '{ > if(NR==1){ > print $1 "\n" $2 "\n" $3 > } else { > print} > }' test # 或者 $ awk '{ > if(NR==1){ > OFS="\n" > print $1, $2, $3 > } else { > print} > }' test
说明:你首先应该注意的是,这里我使用了
awk
语言的分支选择语句if
,它的使用和很多高级语言如C/C++
语言基本一致,如果你有这些语言的基础,这里将很好理解。另一个你需要注意的是NR
与OFS
,这两个是awk
内建的变量,NR
表示当前读入的记录数,你可以简单的理解为当前处理的行数,OFS
表示输出时的字段分隔符,默认为" "空格,如上图所见,我们将字段分隔符设置为\n
换行符,所以第一行原本以空格为字段分隔的内容就分别输出到单独一行了。然后是$N
其中N为相应的字段号,这也是awk
的内建变量,它表示引用相应的字段,因为我们这里第一行只有三个字段,所以只引用到了$3
。除此之外另一个这里没有出现的$0
,它表示引用当前记录(当前行)的全部内容。
- 将test的第二行的以点为分段的字段换成以空格为分隔
$ awk -F'.' '{ > if(NR==2){ > print $1 "\t" $2 "\t" $3 > }}' test # 或者 $ awk ' > BEGIN{ > FS="." > OFS="\t" # 如果写为一行,两个动作语句之间应该以";"号分开 > }{ > if(NR==2){ > print $1, $2, $3 > }}' test
说明:这里的
-F
参数,前面已经介绍过,它是用来预先指定待处理记录的字段分隔符。我们需要注意的是除了指定OFS
我们还可以在\t
,print打印的非变量内容都需要用""一对引号包围起来。上面另一个版本,展示了实现预先指定变量分隔符的另一种方式,即使用BEGIN
,就这个表达式指示了,其后的动作将在所有动作之前执行,这里是FS
赋值了新的"."点号代替默认的" "空格注意:首先说明一点,我们在学习和使用awk的时候应该尽可能将其作为一门程序语言来理解,这样将会使你学习起来更容易,所以初学阶段在练习
awk
时应该尽量按照我那样的方式分多行按照一般程序语言的换行和缩进来输入,而不是全部写到一行(当然这在你熟练了之后是没有任何问题的)。6.awk常用的内置变量
变量名 说明 FILENAME
当前输入文件名,若有多个文件,则只表示第一个。如果输入是来自标准输入,则为空字符串 $0
当前记录的内容 $N
N表示字段号,最大值为 NF
变量的值FS
字段分隔符,由正则表达式表示,默认为" "空格 RS
输入记录分隔符,默认为"\n",即一行为一个记录 NF
当前记录字段数 NR
已经读入的记录数 FNR
当前输入文件的记录数,请注意它与NR的区别 OFS
输出字段分隔符,默认为" "空格 ORS
输出记录分隔符,默认为"\n" 关于
awk
的内容本课程将只会包含这些内容,如果你想了解更多,请期待后续课程,或者参看一下链接内容:
(十二)Linux 下软件安装
Linux 上的软件安装
通常 Linux 上的软件安装主要有三种方式:
- 在线安装
- 从磁盘安装deb软件包
- 从二进制软件包安装
- 从源代码编译安装
这几种安装方式各有优劣,而大多数软件包会采用多种方式发布软件,所以我们常常需要全部掌握这几种软件安装方式,以便适应各种环境。下面将介绍前三种安装方式,从源码编译安装你将在 Linux 程序设计中学习到。
二、在线安装
试想一下,平时我们在使用 Windows 的时候,想要安装一个软件,我们需要在网上去下载对应软件的安装包,接着安装的时候就是不断的去点击下一步,这些流程想必大家已经经历的无数回了,但是在 Linux 下,一个命令加回车,等待一下,软件就安装好了,这就是方便的在线安装软件的方式。在学习这种安装方式之前有一点需要说明的是,在不同的linux发行版上面在线安装方式会有一些差异包括使用的命令及它们的包管理工具,因为我们的开发环境是基于ubuntu的,所以这里我们涉及的在线安装方式将只适用于ubuntu发行版,或其它基于ubuntu的发行版如国内的ubuntukylin(优麒麟),ubuntu又是基于debian的发行版,它使用的是debian的包管理工具dpkg,所以一些操作也适用与debian。而在其它一些采用其它包管理工具的发行版如redhat,centos,fedora等将不适用(redhat和centos使用rpm)。
1. 先体验一下
比如我们想安装一个软件,名字叫做
w3m
(w3m是一个命令行的简易网页浏览器),那么输入如下命令:
apt 包管理工具介绍
APT是Advance Packaging Tool(高级包装工具)的缩写,是Debian及其派生发行版的软件包管理器,APT可以自动下载,配置,安装二进制或者源代码格式的软件包,因此简化了Unix系统上管理软件的过程。APT最早被设计成dpkg的前端,用来处理deb格式的软件包。现在经过APT-RPM组织修改,APT已经可以安装在支持RPM的系统管理RPM包。这个包管理器包含以
apt-
开头的的多个工具,如apt-get
apt-cache
apt-cdrom
等,在Debian系列的发行版中使用。当你在执行安装操作时,首先
apt-get
工具会在本地的一个数据库中搜索关于w3m
软件的相关信息,并根据这些信息在相关的服务器上下载软件安装,这里大家可能会一个疑问:既然是在线安装软件,为啥会在本地的数据库中搜索?要解释这个问题就得提到几个名词了:
- 软件源镜像服务器
- 软件源
我们需要定期从服务器上下载一个软件包列表,使用
sudo apt-get update
命令来保持本地的软件包列表是最新的(有时你也需要手动执行这个操作,比如更换了软件源),而这个表里会有软件依赖信息的记录,对于软件依赖,我举个例子:我们安装w3m
软件的时候,而这个软件需要libgc1c2
这个软件包才能正常工作,这个时候apt-get
在安装软件的时候会一并替我们安装了,以保证w3m
能正常的工作。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
,系统会有一个确认的操作,之后这个软件便“滚蛋了”。使用 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/目录下的内容,如下图:
查看已安装软件包的安装目录
如果你依然在纠结到底linux将软件安装到了什么地方,那么很幸运你将可以通过
dpkg
找到答案使用
dpkg -L
查看deb
包目录信息
$ sudo dpkg -L emacs
dpkg
还有一些其他的参数,这里将作为练习题由你自己来学习四、从二进制包安装
二进制包的安装比较简单,我们需要做的只是将从网络上下载的二进制包解压后放到合适的目录,然后将包含可执行的主程序文件的目录添加进
PATH
环境变量即可,如果你不知道该放到什么位置,请重新复习第四节关于 Linux 目录结构的内容。作业
六、遇到的问题及解决
①
刚开始输入时,不见输入有任何显示,以为反应迟钝出错
解决方法:多试验几遍,结合实验楼中的提示,得出输入是有效地 只需要再继续按ENTER键就可以继续下去
②出现command not found
解决方法:根本原因在于未进行安装,需要先SUDO安装后才能继续下去。
七、实验感想
本次练习报告是本学期的第一次练习,再次进入状态,让自己再次想到了上个学期学习JAVA的时光。本次练习虽耗时很长,但是我却学到了很多,对于LINUX有了一个更加直观得了解,相信通过此次入门练习,我会在今后的LINUX学习中收获更多,学到更多。我也会一如既往认真学习,不断钻研,不耻下问,真正把这门课程吃透。