1、开篇一——基础知识
这里用到的软件是VMware,是一种虚拟化的技术,其实一台计算机就是一台虚拟机,操作系统本身也就是虚拟化的技术,像CPU只有一颗,在某一时刻跟人一样只能想一件事情,只能运行一个程序,但是为什么现在可以同时运行多个进程?这种同时只是我们看到的同时,实际上是操作系统将硬件虚拟化之后提供给程序使用。
如果说虚拟机做好之后,不能连接到物理网络上,就选择edit—>virtual network editor,然后里面有一个VMNET0(桥接网络)通过物理网卡能够跟外在的网络进行通信的一种机制,默认的选择是自动桥接,但是当物理网络和无线网络都开启了,可能就会出问题,所以这个时候就需要手动的选择以下。
power on:开启虚拟机
power off:关闭虚拟机(相当于拔电源)
suspend:挂起虚拟机(使操作系统保持当前的状态,下次开机依然能够恢复该状态,相当于一个快照,让计算机静止在这一刻,下次开机还是从这一刻开始)
reset:相当于按重置按钮,冷重启
快照:应用在做一些快照方便系统快速恢复到制作了快照的地方,非常方便,所以在平时玩的时候,装完操作系统马上制作一个快照,然后随便捣鼓,搞坏了马上还原就行了,非常方便!
对VMware来说ctrl + alt + insert(重启) 马上按F2进入虚拟机的BIOS界面,后面需要进行调整的就一个就是BOOT(boot sequence启动次序),调整启动次序的。
系统在启动的时候首先是加电自检(POST:POWER ON AND SELF TESTING):计算机只是一堆硬件,根本不可能自动的自检,硬件本身是没法进行任何计算工作的,实际上执行的是一条条指令(程序是由指令和数据构成的)来实现的,因此CPU只有加载到了指令之后才能执行,那么指令在什么地方存储的呢?内存是易失性存储器无法存储东西的,所以应该放在辅存上,这就是BOOT的作用了,辅存设备有很多,所以到哪里去加载指令就看BOOT的顺序了,但是系统在刚加电的时候,这些能够检测硬件且给硬件排序的程序又是从哪里来的呢?这就需要提到计算机系统的自举能力,计算机系统是依靠额外设备来实现的,就是BIOS。
要理解BIOS就要理解下计算机的体系结构(冯诺依曼是计算机体系结构之父)了:
那么计算机一个电子设备为什么能进行运算呢?
计算器+控制器=(约等于)CPU
运算器从存储器里面去拿到数据,进行运算,然后将结果又放到存储器里面,但是CPU怎么知道到内存中去取哪些数据?运算完成后数据又放到内存的哪个地方?存储器指的内存,内存是一个编址存储设备,每一个存储单元8位(一个字节),每一个字节都是有地址的,内存是平面编址的,每个存储单元在全局上有一个唯一的编址,这个地址是使用数字的方式进行引用。
要知道计算机的核心设备就是运算器,加法器是最基础的,要做加法就需要加数和被加数即可进行运算,但是有一些特殊的场景,就是进位的情况(甚至连续进位的情况),即在进行下一位计算的时候还需要考虑上一次计算的进位情况,加法器要计算就需要取数据,指令中就会告诉运算器到内存的哪个地方去取数据,接下来就是由控制器控制着去内存中取数据,对于控制器而言,控制器需要接受控制指令,同时运算器要运算数据需要取得数据,传输数据的线路称为数据总线,对于控制器而言获取控制指令的线路成为控制总线,指令同样是存储在内存中的,计算完后,由控制器控制将数据存储在内存中。
存储器初始的时候,里面是空的,什么都没有,作为用户来讲,仍然需要将要执行的程序首先放到内存中去,然后让运算器和控制器进行相关操作,那么就需要一个外围的设备辅助着将用户的指令和数据存储在内存中,从而运算器和控制器可以从内存中取数据进行运算,运算完成后,还需要将数据从内存中搬到外置的地方,或者通过显示器显示出来,像显示器就是输出设备,所以计算机中,运算器、控制器、存储器是核心,输入和输出是用来跟用户进行交互的,用于辅助计算机的运行的。输入输出设备又称之为I/O设备。
计算机继续需要两根线,一个传输加数,一个传输被加数,那么计算32位的加法,这该需要多少根线啊,所以说能不能只用一根线既传输加数又传输被加数又传输指令,这就叫线路复用。但是CPU如何知道传输的是数据还是指令呢?通过加控制位就可以解决了,但是还有一个问题就是如果一根线上既传加数又传被加数,加数传完后就一定需要一个地方来暂存加数,不然被加数一过来,加数就没了,所以就需要一个暂存的地方,就称之为寄存器。CPU中最核心的组件:运算器、控制器、寄存器。
虚拟机就是用软件的方式模拟了运算器、控制器、寄存器等,但是这是结合实在的物理设备来虚拟出来的。
CPU要想执行指令,这个指令必须是在内存当中,而内存当中必须有那么一段指令事先放好了才能执行的,但是计算机刚开机的那一刻,根本就不知道是否有键盘,也不知道是不是有显示器,所以不知道从哪里输入数据,从哪里输出数据,而且内存也无法事先保存数据,所以就需要借助额外设备了(就是所谓的ROM(read only memory)只读存储器,里面就是此前的适用于该计算机的一堆指令,这些指令可以映射到内存当中去,还有一个额外设备,叫元芯片,芯片里面放的指令不会丢失,就算计算机没有电也不会丢失,一开机,计算机会自动的,由硬件逻辑完成的,将芯片中的程序映射到内存中,在内存的最开始的那一段,然后CPU就会去读取那一段指令,去探测是不是有键盘、有没有显卡、有没有硬盘之类的),存储器称之为RAM(random access memory)随机访问存储器,这个过程就是加电自检。理解这个过程非常重要,因为后面的调优操作就是去调整内存中的数据是如何排列的,以及CPU是怎么去运行程序的。
前面提到的内容还存在一个问题,就是外围的I/O设备可能有很多个,键盘、鼠标都是输入设备,硬盘既是输入又是输出设备,同样是I/O设备,当某一个时刻,需要从硬盘读数据的时候,如何通知硬盘而不是键盘,要读数据了,输入设备那么多,还有就是输出的时候,如何知道要将数据输出到哪个地方,是通过显示器输出还是通过硬盘输出的。这就是内核设备如何跟外围设备打交道的问题了。
比如说通过一根总线将外围设备连接起来,但在某一时刻怎么知道是哪个设备传输的数据呢?比如说敲了一下键盘,那么如何知道是键盘敲的还是鼠标点击的呢?这如果要知道的话,CPU就要时刻不停的去看看键盘是否敲了,鼠标是否点击了,但是如果一天都没有敲键盘,那么CPU的轮询就白白浪费了,效率非常低,所以如果反过来,让键盘去通知CPU,如果敲击键盘了,就通知CPU键盘被敲击了,快来处理这个事件,这个机制叫做中断interrupt(硬件通知机制),但是中断发生了,如何知道这个事件是键盘还是鼠标呢??很简单,就是需要一个控制芯片,在计算机中有一个芯片,叫可编程中断控制器,这个控制器跟CPU针脚是相连的,CPU通过这个控制器就可以知道是哪一个设备发生了事件,这个控制器的每一根线表示一个设备,比方说第一根线给键盘使用,第二根线给鼠标使用,那么当第一根线上电位发生变化时,CPU就会知道是键盘发生了事件。这里只需要知道,外围设备就是通过不停的中断来跟CPU进行交互的。但是如果中断多了,主机的效率就低了,但是不中断又不行。
【补充,待查】前端总线:FFB
高速总线控制器,需要大量数据传输的,需要工作在比较高的频率下的,需要快速进行数据传输的。
慢速的,像键盘、硬盘这些慢速设备,南桥汇总后接入到北桥,大多数I/O设备都接在南桥上,这些设备经过南桥汇总后,由一根线汇总到连到北桥,由北桥再转给CPU。
但是现在的结构发生了变化,北桥不是再用来控制内存了,而是CPU直接跟内存相连,北桥只跟南桥相连,以及其他总线的控制,这样速度会更快。
程序的局部性(时间上的局部性和空间上的局部性)原理:实验证明程序是遵循局部性原理的,表示的是在CPU读取程序数据时,为了尽量少的在内存中读取数据而是在缓存中读取数据,所以在CPU加载数据时,会将临近时间的数据都加载到内存中,以及数据所在的附近的数据也加载到内存,这样做可提高程序运行的速度。如果懂局部性原理的话,开发的程序的执行效率是非常高的。
计算机执行程序都是指令通过CPU的某根针脚来执行的,但是生产CPU 的公司却又很多,也就是说其CPU的运行机制各不相同,而程序的运行又依赖于CPU的运行机制,所以程序员要想写程序在特定的CPU上执行,就必须写机器语言,但是这显然是不现实的,所以生产CPU的公司有在CPU上添加了一层叫微码(汇编),但这时候程序员是容易理解了,但是机器难于理解,所以这其中又需要一个编译器,编译器就是将程序员写的程序转换成机器语言,在CPU上运行,注意汇编跟硬件的结合程度还是非常高的,执行效率还是非常高。后面为了进一步的方便程序员开发,又诞生了高级语言
这种语言有一种非常好的特性(本身是需要先转换成汇编,然后再翻译成机器语言):
高级语言要想运行就要一种额外的机制来弥合多种芯片之间的不同。如下图所示,在每家公司生产CPU的时候,为了屏蔽其底层的差异而为其CPU芯片制作了一个中间层为上层程序提供了一个公共的API(应用编程接口),API就是在不同的CPU上利用其CPU上的汇编而写出来的具有相同功能的程序,这个程序本身不会自己运行,而是告诉上层程序,不用关心CPU,而是虚拟了相同类型的执行环境,库是一种虚拟设备,
硬件架构:(CPU芯片的不同系列)
ARM(英国的一家公司):只负责生产知识产权,不生产芯片。省电、性能也不错
X86: intel
32位:理论寻址范围为4G
X64:
64位:
安藤:原来属于惠普的
惠普现在也有一个:alpha
UltraSparc
Power:第一个主频超过4G的CPU
M68000:摩托罗拉公司的 M68K
PowerPC:早期苹果的系统
linux基本上支持所有的CPU类型。
Windows
Linux
Unix
HP-UX
Solaris
AIX
SCO UNIX
UnixWare
Android
OS/2
……
我们的计算机只有一颗CPU,一段内存,有输入输出设备,那么在某一刻能运行的程序有多少呢?多个程序是如何运行的呢?为什么这些程序看上去会是并行执行的呢?计算机很快输入输出设备很慢如何处理呢?
在穿孔纸带上放多个job,一个job执行完成之后,CPU会自动的加载另一个job来执行,但是这种批处理在某一个时刻仍然只能执行一个程序。而且这种情况会造成严重的CPU运算资源的浪费,因为在程序运行的过程中难免会有I/O操作,这些操作在执行的时候,CPU是啥事没干的,这样就会使得CPU计算资源得不到充分的利用,而要想CPU时刻处于时刻繁忙的状态,那么就需要将资源切割开来。
程序想运行需要的核心资源就是CPU和Memory,CPU无法分片,但是可以一个程序执行一会,再去执行以下另一个程序,把CPU分成小的时间段来执行程序,这样的话就需要执行一会A程序后要保存下现场,比如说CPU运行A程序5ms,再运行下B程序5ms,这样交替,所以需要保存现场。对于内存的话,可以将内存进行分段,每一段都有1 2 3 4 ,每一段都有地址的起始位,这样程序就不需要改了。然后一个问题就是内存的大小可能不一样,就需要用虚拟地址空间了,每一个程序员不需要管有多少内存,就当32位系统就有4G的内存空间,64位系统就是内存无限大的,因为程序实际在运行的时候是用不了那么多内存的。前面说的5ms是每个程序执行的小片段时间,但是程序本身是无发做到的,这是由操作系统来控制的,操作系统就是一个软件,运行在硬件上,负责管理硬件资源,将硬件资源提供的计算能力(cpu切割成多个片分配给多个程序,内存分成多个段,)然后在进程之间进行协调,操作系统还负责程序的运行、终止、切换的操作。操作系统就是一种通用软件,不完成具体的操作,只是协调其他的具体的程序工作的。
前面提到库是用来弥合底层硬件的不同的,库是一堆的程序,这些程序比较独特,任何一个程序都有一个执行入口,但是库不一样,它没有执行入口,不能独立运行,必须被调用才能执行,但是在执行的时候可以提供一个统一的调用机制,就像剃须刀,不管是哪个公司生产的,最终功能、使用方式是相同的就可以了。库也是一样,只提供调用接口,供程序调用。
【注】有了操作系统之后,任何程序想执行都不能直接跟硬件打交道,要想使用硬件功能必须通过系统调用跟硬件打交道,操作系统就像一个代理人介于程序和硬件之间,进行计算机硬件的管理工作。
系统调用是操作系统封装的偏底层的硬件访问接口,由于系统调用非常的底层,程序员在写程序的时候的需求如果直接使用系统调用的话,就需要做很多其他的操作才能完成,所以专门有人将系统调用再次的进行了封装,做成了更高级的接口,就是所谓的库(API)。打比方说要用C语言来写一套程序并不是通过系统调用来写的,而是通过调用库来写的。(相当于就是程序员去调用别人已经写好的功能去实现一些更高级的功能而已)
(理解:比喻说人人都要吃馒头,可是系统调用就提供麦子,如果人们需要馒头还需要去取麦子,磨面粉,做馒头。。。非常麻烦,所以才会有人去将系统调用做更高层次的封装,直接把馒头给做好放那儿,因为馒头就是一个公共的东西,人人都需要)
(再次理解:系统调用是为了做的更简单,更容易被广泛的使用的,这就像极了社会的层次结构,社会的底层是一些老百姓,提供麦子、生产一些物品的原料上上层提供,但是普通的人只是要吃米饭、馒头、包子等,不可能去买麦子自己生产吧,所以就专门有人来做了这么一件事情,将麦子买过去进行加工、生产成馒头、包子等,那么人们需要吃就直接买就行了,这个比喻就恰当很多了,然后像超市是一个非常复杂的组合体,里面的很多东西也都是用的别人加工好的一些物品,然后对外提供更全面的服务的)
程序员是根据库来进行编程的,在windows里面调用windows提供的库来编程,在linux里面用linux提供的库来编程,一旦库不一样,在windows里面开发的程序在linux里面就使用不了。
在图中可以看到一些应用程序是在库的基础上写的,一些应用程序直接调用内核提供的功能,但是有一个问题就是,在操作系统启动的时候,这个程序未必会运行起来,只是说程序具备了运行条件。通常运行程序有几种方式:(1)让操作系统已启动就让程序自动的运行起来,(2)按需手动启动(交互式程序)
交互式程序是需要跟用户来进行交互的,而用户来讲,我们使用计算机无非就是输入设备(键盘、鼠标等)和输出设备(显示器等),那现在的问题就是,我们敲击一下键盘,我们的信息一定是由CPU先接收的(通过中断先到达CPU),那CPU发现我们敲下键盘以后,它怎么知道是哪一个程序呢?CPU其实并不知道我们敲击键盘的信息意味着什么,比如说按下ctrl+C,那是不是复制粘贴,还是只是随便按下什么键,为什么ctrl + c就是复制,对于某些编辑器来讲,必须将键盘上的这个键解析成对应应用程序所能理解的功能,但现在问题是我们敲下的键盘首先是拿到CPU的,但是我们知道能够跟硬件交互的只有内核,所以CPU在获得这个信息以后,首先通知内核来进行处理的,而不是说直接交给word这类的软件,所以这个时候内核必须要能够在CPU上运行起来,并且接着去处理这么一个信号,当然内核是知道这个程序是由哪个进程发起来的,整个系统资源的监控包括上层运行的应用程序的资源监控都是由内核来完成的,所以内核会知道,到底是哪个进程处于当前焦点进程,而负责接收这么一个快捷键,因此再由内核转交给应用程序的,所以一个应用程序的执行过程是这样的,但是操作系统本身也是一个应用程序也需要运行起来,它既然需要运行,就需要指令和数据,而指令和数据是放在内存当中的,那就意味着在我们的存储器当中,既有内核还有其他的应用程序,那么如果一个恶意的应用程序,能够直接访问内核的话,能够直接跟内核进行交互的话,能够直接去修改内核中的某些数据的话,这意味着系统的稳定性将无法得到保证,所以说就必须要有一种机制将应用程序和内核隔离开来,通常情况下,像在intel这一类的平台上,它会提供所谓的保护机制,或者叫保护模式,一般我们的CPU会有四个级别,是同心圆的四个环,最内存,我们称之为0级别(或者叫第0环),0环也称之为特权级别,只有内核才能运行在特权模式下,而其他应用程序只能运行在最外层级别下,中间两层没用,所以任何时候,应用程序是不能访问内存当中,处于0级别的内存区域的,我们刚刚提到过,CPU和内存之间是紧密结合的,所以CPU的0级别就会映射到内存中某一段处于保护的空间当中。
当我们的程序运行起来之后,在我们的内存当中是分成两段的,事实上是三段,最底层的一段是叫BIOS的映射程序,POST加电自检以后,BIOS自动的就映射到内存的开端之处了,接下来就是载入内核了,在内存中,接下来的空间就是内核空间(kernel space)了,而后的一段空间是被多个应用程序所共享的,但是这样会存在很多问题,是比较粗糙的,只是便于理解的,这样去划分内存是非常容易产生内存碎片的,其实操作系统是一个非常复杂的东西,需要管理的任务,需要完成的功能是非常复杂的。
再次回到计算机上程序启动的问题,程序的启动有一种叫按需启动程序,那么如何让操作系统能够接受用户的命令,就说我用户输入命令指示要启动word,那么操作系统就能够将word启动起来,那也就意味着还需要给我们的操作系统提供一个特殊的应用程序(shell),shell是能够实现接收用户、理解用户的命令并且将它传输给内核,并且有内核指挥着某个应用程序启动的这么一个界面(有时候也称之为接口,这个要能够转换过来,是同一个意思),那么shell本身用来干什么呢?首先是提供一个用户可以跟它交互的界面,其次还要将用户的指挥行为翻译成计算机可以理解的命令或者内核可以理解的命令,比如说在桌面上双击一个图标,为什么就能够被解析成打开一个应用程序呢?这就是靠内核进行指挥了,但是能够提供一个界面让用户进行双击,并且能够显示一个鼠标的样子,这其实是由界面提供的,也就是shell提供的,所以说没有shell的话,用户就没法跟计算机进行交互,shell有两种,一种是GUI(图形用户接口),一种是CLI(命令行接口),无论是GUI还是CLI,其实也是应用程序,在不同的操作系统上,他们可能提供的有不同的替换的版本,像Linux上面常见的就有三种图形界面,在这样一个接口上,如果关掉了这个接口,那么基于这个接口的所有程序都会关闭,因为在这个接口上启动的程序,跟这个接口有着紧密的关系。
从上面的这些内核提供的功能可以看出,操作系统是一种通用软件,而不是针对于某一种应用程序的。
接着说前面提到的批处理操作系统,讲下操作系统的发展历程:
由于批处理系统无法真正发挥硬件的真正能力,所以在这个时候,有三个组织:
GE(通用电器),美国的电报电话公司AT&T的BELL(贝尔实验室),还有麻省理工大学的人工智能实验室(MIT)共同研究出了比批处理复杂高效很多的多任务多用户的系统,技术非常复杂,使用汇编进行开发的,基本的功能都已经实现了,且可以供多个用户共同使用。那些人给这个系统起了个名字叫Multics。而且这些计算机科学家在后面还接着为这款操作系统做了很多完善,加了很多功能,但是随着不断的添加新功能,他们有些迷失了发展的方向,所以后面有些组织渐渐的就退出了这款系统的开发,最终就剩下MIT接着进行这款系统的开发,由于BELL实验室退出,实验室中的很多工程师就空闲下来了,这其中包括Ken这个家伙,这家伙当时在Multics主机上研发了一个游戏叫space travel,是一款打飞机的游戏,在现在看来是很丑陋的,这款游戏只能运行在Multics上,由于bell实验室的退出,使得这款游戏无法跑,所以他就很郁闷,这样就到了72年左右,在当时,最著名的生产计算机的公司,除了IBM之外,还有一家叫DEC,它生产小型机、中型机、大型机等,有一些还是非常受欢迎的,当时ken申请bell实验室给他批一台PDP-11给他研究,但是实验室不批,所以ken非常郁闷,在实验室闲逛,然后在一个角落里,发现了PDP-7的一台机器,是一款非常落后的主机,但是他就是拿着PDP-7来研究他的游戏,space travel是一个应用程序,应用程序要想运行就必须依赖于内核,所以ken不得已只能自己去开发一个内核来跑他的游戏,就是模仿他对Multics的理解来开发的,最后他成功了,然后他就在实验室里到处晃推销他的游戏,但是没人对他的游戏感兴趣,都是对他的系统感兴趣,但是很遗憾的是,汇编所开发的程序,是跟硬件平台紧密结合的,想要在其他机器上运行是不可以的,所以PDP上开发的想要运行在其他机器上是不可以的,所以在实验室的要求下,ken又不得不将他的程序移植到其他主机的系列上,他又成功了,而且运行的还不错,接着此后一年,ken的这个系统风靡bell实验室,后来他的一个同事给他的系统起名为unics,因为当时他的这个系统功能非常简单,后来才改成了Unix,但是这个时候Unix一直都是使用汇编语言来研发的,性能是很不错的,但是移植起来比较困难,为了能够扭转这种劣势,当时Ken Thompson的一个同事丹尼斯·里奇,这个家伙看到ken没事就在那里移植系统,他就在想能不能使用高级语言重新开发Unix,这样就只需要使用编译器在不同的平台版本上进行编译就能够完成Unix的移植了。因为高级语言对底层硬件的依赖程度是非常低的。像C语言,虽然称之为高级语言,但是同时也兼具低级语言的特性。当时他们两个人一商量,不谋而合,然后他们在B语言的基础上,添加了变量、指针等新的特性,然后称之为C语言,而后这两个人完全使用C语言重写了Unix,当时这是一个非常胆大的尝试,因为高级语言的效率比低级语言至少低30%以上,但是他们准确的意识到计算机的以后肯定会得到很大的发展,发展到可以忽略这种差异,所以他们没有犹豫的用C语言重写了Unix,然后他们两个人在计算机通讯杂质上发表了一篇论文专门说他们的Unix操作系统,计算机通讯杂质每年都会举办年会来聚集来自全球各地的计算机科学家来探讨计算机的发展趋势,在那年的会议上ken他们也参加了,与会的很多科学家对他们的系统非常感兴趣,所以期望获得一份去学习和使用,他们因为不得已无偿提供给了他们,此后几年,大概到了1976的样子,ken(美国的工程师有一个非常好的福利,如果做出了突出贡献的人,可以放一年的年休)当时ken去美国加州大学学校去任教,当时那个学校有一个学生bill joy,他成立了一个操作系统研究小组(BSRG),专门研究Unix,改进、修复bug,提供新功能等,由于ken的加入,是的这个研究组成为当时Unix研究所中的领头羊,当时由于网络(美国军方网络)的兴起,而此时他们就需要一种协议,能在这个网络中传输网络数据报文,而这个协议的研究,他们不期望在一个封闭的系统中来实现,而当时Unix以及BSRG正好符合要求,所以他们就将这个协议的研究交给了bill joy这个小组,后来不久,像包括TCP网络协议中的拥塞控制等包括各种功能,都诞生在bill joy所领导的小组研究的Unix系统平台上,后来柔和了各种新功能,然后形成了一个单独的操作系统向外发布,并且重新取了一个名字叫BSD(Berkeley system distribution)而且可以从中谋取盈利,而bell实验室当时那个原生的那个Unix就叫system +版本号,后来bell实验室被卖了,也就是不受AT&T的限制,所以一出来之后,立马就封装了商业版的Unix向外卖,并且还跟BSD打起了口水仗,打官司打了10年之久,到此为止,Unix的发展几乎陷入停顿状态。大概81年左右,PC兼容机出现,当时在美国很多公司就开始生产PC机了,但是任何一个机器没有操作系统是没法用的,Unix又没有往PC机上移植(Unix程序员不屑于把Unix移植到PC机上),于是美国的一个教授开发了一个操作系统叫做(CP/M)买一个PC需要2~3万美元,然后买一个操作系统又需要2~3万美元。这个时候在美国一个小公司Microsoft成立了,当时刚成立就3个人,当时也没啥干的,就卖basic(当时的一种脚本语言)的编译器,再就是包装发行卖Unix,他们的Unix还起了个很奇怪的名字叫Xennix,但是他们卖Unix的热情没有持续太久,因为比尔盖茨的一个好友的好友在另一家公司上班,是一个程序员,非常牛,仿照PC/M花了四个星期时间写了一个能在PC上运行的小系统,然后比尔盖茨敏锐的发现这么一个商机,然后利用他母亲(IBM董事会成员)的关系找到了IBM公司的董事长沃森,跟他谈,说有一个系统能装在PC机上,然后也不需要几万美元,只卖授权,就是说IBM卖一台机器,就给比尔盖茨几美元,然后比尔盖茨花了几万美元从那个程序员手上买断了那个系统,然后敲敲打打的修改了那个操作系统,取名为DOS,然后后面的故事就是PC机非常火,比尔盖茨也靠这个赚了一大笔钱,DOS也叫磁盘操作系统,是单用户单任务的操作系统,很不稳定,经常崩溃,但是在当时是非常好的,但是在另外三个人创立一家公司后,他们的前景就不那么好了,这三个人的领头的就是乔布斯,后面乔布斯那三个人看着PC机大卖特卖,他们也决定去折腾PC机,当然不是像IBM一样做PC兼容机了,他们是想做一个性能比较强的,超出于PC兼容机的,当时因为乔布斯非常崇拜图灵,因为图灵当时是一个同性恋,当时是不被接受的,所以被囚禁起来,然后郁闷了,就咬了一口涂有氰化钾的苹果死了,所以乔布斯的公司就取名苹果,而且是被咬了一口的苹果。乔布斯曾经去游荡过施乐公司的实验室,发现了其公司一个团队生产的鼠标以及基于图形界面的操作程序,然后乔布斯很敏锐的觉得图形界面操作肯定是以后的主流,因此跟施乐公司的老板谈买下了他的这个技术,回去经过一番研究,最终在苹果2代推出了他的图形操作的操作系统,这无疑是对比尔盖茨的当头一棒,然后比尔盖茨使用各种手段从乔布斯那里把图形操作的程序骗来了一个副本,在DOS的基础上继续开发图形操作系统。(伟大的企业家都是靠偷的)。由于Unix商用了,卖钱了,所以很多科研机构就无法免费试用Unix了,那么在荷兰的一个大学的一个教授一直在使用Unix进行教学,当Unix不能用之后,很不爽,于是决定自己开发一套操作系统进行教学,诞生了取名:Minix,然后他推广,用这套系统到处教学,但是因为他是在他自己的机器上开发的,所以别人用需要自己写驱动,很麻烦,所以很多其他的牛人都期望将他们写的驱动添加到他的系统中,但是那个老教授不同意,不愿意别人的驱动污染他的系统,所以这让很多黑客们很不爽,其中就包括一个叫Linus的家伙,他因为不爽,也自己写了一个系统取名Linux,然后他给他的系统写了一个公告,开放他的系统,所有人都可以改他的系统,只需要告诉作者添加了什么,改了什么就可以了,这样使得Linux得到了迅速发展。当然这是一个历史契机,并不是Linux天生就有这么顽强的生命力,因为在80年代的时候,在麻省理工大学有一个著名的教授叫Richard Stallman,他认为程序是全人类的,不是为某一个流氓公司所独有的,他举起了自由的大旗,freedom,他倡导软件应该公开给全球使用,谁也不应该将软件封闭,将软件拿来卖钱,很多程序都非常赞成他的这种做法,因此全球很多黑客级的人物都纷纷宣布支持他,因此Stallman专门成立了一个组织叫做GNU它是一个递归缩写(GNU IS NOT UNIX),他发起了程序界的共产主义运动,他认为程序是共产的,而共产主义的标志就是共产主义宣言了,所以GUN组织的这种运动也需要一种宣言,因此GPL诞生了,GPL(General public license)相当于共产党宣言,而GNU相当于一种运动。他的GNU运动和GPL宣言受到了全球很多组织的支持,他们纷纷为GNU贡献自己的力量,这就包括Stallman当时研发的Emacs:文本编辑器,在Linux上非常流行,GCC:GNU的C编译器,GCC是非常牛的,中国到现在依然没有一个像样的编译器。回到Stallman的GNU运动,由于程序是要运行在操作系统上的,所以Stallman的思想即使再好,没有系统也是白搭,很多支持Stallman的人就要求Stallman能有一款操作系统了,正好这时候,Linux出来了,所以完美的结合了,所以才有后面Linux飞速的发展,Linux也是遵循GPL的,Linux本身也算是GNU的,这里要注意,Linus当时写Linux的时候只是一个内核,并没有写相关的库,Linux上的库叫做glibc,gcc是上面的编译器,利用glibc和gcc也可以移植过来很多程序,比如说像bash(GNU的),一个命令行的界面,这一出现,使得黑客迅速团结在Linux周围,是的Linux在短短几年(91年0.1版,94年1.0就诞生了)1.0版的Linux就已经可以跑在很多机器上了,所以说当我们提到Linux的时候,只是指内核,真正意义上的我们使用的Linux是GNU/Linux,GNU组织为Linux内核周围开发了很多外围的程序。需要注意的是,无论是GNU的软件还是Linux的内核,它们都是源代码(使用C开发的程序),任何语言开发的程序要运行就必须编译成二进制。但是能有这种能力的人不多,而且要想编译一个程序,这个编译器要能够运行才行,因此必须要借助一个很好的已经能够运行的系统,上面的编译器才能编译,但是更重要的是,编译必须要两个平台完全一样,也就是说如果编译之后期待它能在X86平台上运行,就必须要在X86的机器上编译,如果说想在A的CPU上编译,要在B的CPU上运行,这种编译叫交叉编译,但这要麻烦的多。所以后面就有组织专门负责编译Linux和外围的程序,并且将它打包成二进制可安装的程序发行,这种组织就包括93年成立的redhat,还有91年的SLS,还有92年的debian,德国还有三个大学生,发行了SUSE,这些人都不是Linux的开发者,只是做了编译工作,这些人被称为Linux的发行商。但是最开始软件包都是被打包在一起提供给用户的,这样非常不适合于单个软件包的管理,这时候,debian就专门提供了一个软件包管理器,叫dpt(debian package tools),后来,redhat模仿debian做了一个rpm,后来有了这些管理器之后,软件都是由软件包管理器来进行管理,方便的实现查询、安装、卸载等功能,但是因为GPL的规定很恶心,比如说你公司使用了GPL的20行代码,然后自己开发了10万行代码,那么你也是必须得开放你的源代码,这就是很恶心的地方,然后大大的阻碍了自由发展的进展,然后后面又改进了GPL,LGPL(lesser)更宽松的限定,还要GPLv2和GPLv3,这里注意了在公司如果想用开源软件的话,一定要注意看清程序是遵循的哪个协定,不看清楚可能会引起各种坑爹的麻烦,GPL还是很严苛的协定,还有一些组织有自己的协定,像BSD、Apache都有相关协定。CentOS:community enterprise operation system,不提供服务,不提供保证。fedora也是一个版本,版本更新特别快,为企业级使用提供测试环境的。mandriva:主要用在桌面上。SUSE被收购了,现在属于Novell公司。debian是目前唯一一个不受商业公司支持的公司,它的所有者都是自发的来维护的,但是debian比较难用,一般都是高级用户使用,红帽适合入门使用。Ubuntu:还有一个Mint(绿色的主色调)比Ubuntu做的还好看,比Ubuntu还好用。国内用的最多的还是centos。
以上介绍的就是Linux的由来了!!!!
Linux内核版本:0.1、1.0、2.0、2.2、2.4、2.6、3.0等
Linux安装:
装系统最好能按照我们的需求去装,输入一堆的命令去装
命令提示符:prompt(表示立即可以输入命令了),对bash来说的
#:root
$:普通用户
输入命令:COMMAND回车(敲下回车之后,会由shell将命令交给内核,由内核判断这个程序是否具有可执行权限,从什么地方开始执行等,如果程序不可执行,内核就会返回一个错误。
命令格式:命令本身(必须是可执行程序的路径,或者是一个命令或者是一个脚本的名字,其他的一律会报错的) 选项:修改命令的执行方式的,选项又有短选项(-)和长选项(--word)之分,很多命令一般都有一个短选项一个长选项,注意选项可以有多个(用空格隔开),如果是短选项的话,多个选项之间可以组合起来(次序并不重要,但是有一种情况例外(待补充))(如:ls –a ls -l)在一些命令中的一些选项是可以带参数的,这个要留意一下 参数:指的是命令的作用对象,命令生效在什么地方,参数可以有多个(空格隔开)
su(switch user):切换用户
#su – 用户名 如果命令有一个中括号表示可省略的。(半切换)
如:su student
#su –l student(完全切换)
passwd:修改当前用户密码,对于管理员而言可以随意改成其他密码,而对于普通用户而言,一般的默认策略是,必须要符合密码复杂性规则(密码要足够复杂,一般在数字/大小字母/小写字母/字符四选三组合即够复杂了,然后就是密码要足够长,至少大于7)
【补充GUI】Linux下的图形界面(GUI):
Gnome:使用C开发的
KDE:使用C++开发的
XFace:简洁的,方便使用于嵌入式设备的
【补充CLI】linux下的CLI:
bash:最常用的,也是默认的shell,开源的shell
csh
zsh
ksh
tcsh
在windows上最明显的库就是dll(动态链接库),这在Linux上体现就是.so文件(shared object,共享对象)
Linux装好后,Linux就会给我们提供一个登陆界面,这个登陆界面就是验证用户的身份信息的,每一个使用者都应该有一个用户名,我们操作系统上有很多的资源,很多文件,这些文件可能被很多现实中的人所使用,而A这个用户创建的文件不期望被B这个人访问到该怎么办?也就是说我们需要对文件设定权限,但是权限设定后,怎么去说这个文件可以被谁访问,不能被谁访问呢?显示的用户有A和B,所以我们需要将用户的标识也映射到系统中去,这就是所谓的用户名的概念,当然对我们使用者来讲,我们使用的是用户名,但是对计算机来讲,计算机所能处理的最快的资源不是字符,而是数字,其实我们的计算机识别我们每一个用户靠的是数字,也就是用户的ID号,称为用户ID(identifier),用户名是公开的,所以用户名不能用来作为限定用户是否可以访问资源的认证标识,下面介绍下认证机制:authentication,认证的过程说白了就是鉴定用户就是他所声称的那个人的一种机制,密码是一种认证机制,还有像手纹识别等,其中密码和密钥是最常用的,但是认证不代表全部,因为任何一个人通过认证都是可以进入系统的,但是还需要进行授权:authorization,授予某一个用户某种权限,但是给了某一个用户授权并不代表他就可以胡作非为,所以还需要做审计(他权限之外的审计):audition(大多通过日志来完成的)。
当用户正常登陆以后,显示的是命令提示符(prompt):
就是说可以在下面输入命令了,注意一定要是命令才行,当然这里的命令既可以是二进制的程序,也可以是脚本文件,只不过对于内核而言,它是严格区分两者的不同的,然后前面的一个问题是一个程序是如何被启动起来的,到底为什么能执行起来?这个暂时不去深究,但是要明白,一般一个可执行程序一定要一个执行入口,像库虽然可执行,但是却没有可执行的入口,那么怎么算是有执行入口呢?
这个二进制文件开头处有一个特殊字符,或者有几个字节是非常独特的标识,这个就称之为程序的魔数(magic number),这个魔数可以标识二进制程序的执行格式,还需要注意的一点是在windows上执行程序的魔数跟在Linux上执行程序的魔数是不一样的,它们所理解的二进制格式也是不尽相同的,所以就算两者的库完全一样,windows上的C库和Linux上的C库完全一样,在Linux上编译的程序也未必能在windows上运行,像在写脚本的 时候,开头总是#!/bin/bash,其实这就是给这个文件指定一个魔数的,它也被称为shebang。当我们在命令行下写下一个命令的时候,就会有bash将我们的命令提交给内核,由bash提交给内核,内核就会去找这个执行程序的魔数,看它是不是一个可执行的格式,以及是不是当前内核可理解的可执行格式,如果是就执行起来了,如果不是就拒绝运行,当然是不是会真的执行,还要取决于权限还有一些复杂的外围机制。
列出、列表:列出指定路径下的文件,目录也是一种文件,就是比较特殊而已
在Linux中,目录不是文件夹,仅仅是路径映射而已。
路径指的就是:从指令起始点到目的地所经过的位置,系统上之所以会用到路径的概念只是为了层次化文件管理的一种机制(理解:就是全国人民的管理一样,如果把全国人民全部放在一个区域进行管理的话,是会非常乱的,所以才会将全国人民划分成不同的区域,又是分省的又是分市的等等)层次化的结构可以利用非常短的路径非常快的追溯一个目标的。再比如说,如果所有的文件都放在一个文件夹下,所有的文件有10万个,现在要你找一个文件,那么这样的话时间复杂度是非常高的,而层次化的管理优势就体现出来了。层次化的管理文件就称为文件系统(file system)。对于Linux而言,所有的文件都是属于当前系统的,所以应该有一个制高点,从这个制高点开始就能找到所有的文件,Linux的目录结构通常被称为树形的目录结构,从根目录开始往下找称之为绝对路径,还有一种路径叫相对路径,任何时候我们登陆系统都会处于一个目录当中,打开windows同样,在桌面上也是一个目录,这个目录称为当前目录,也叫工作目录,相对路径:相对于当前目录。上面所说的就是Linux文件系统的一个大致的框架,在Linux系统中,一级目录有一个规定,必须要存在这么些个子目录,这是一种规范,叫做文件系统层级结构标准,这个里面就规定了,有些目录必须存在,而且这些目录里面要放什么类别的文件(这些是要记住的,后面会细讲,现在只需要知道它是层级化的即可)问题:文件名是不是文件的数据?像这些属性不是属于文件的一部分的,比如说我们向系统中存储一个文件,然后后面可以根据文件名进行查找,那么文件名放在什么地方?
说了这么多就可以理解ls命令了,当ls命令没有跟参数的时候,它是有默认值(缺省值)的,也就是显示当前目录下的文件
pwd:print working directory,显示当前工作目录,在linux中,最顶级的目录用“/”表示。
ls命令显示的内容中,蓝色显示的是目录,绿色表示有执行权限
当然ls还有很多辅助性的功能:
ls –l(长格式)显示文件的完整信息(属性信息)
第一列共十位:第一个是文件类型:
-:普通文件
d:目录文件
b:块设备文件(block)
c:字符设备文件(character)
i:连接文件(symbolic link file)
p:命令管道(pipe)
s:套接字文件(socket)
在/dev目录下很多c开头的和b开头的文件,在/tmp目录下可以看到像s开头的文件
接下来的9位:指的是文件权限(每三位一组)每一组里面分别是rwx(读写执行三种权限,如果没有则用 - 表示)
接下来的一位:文件硬链接次数
接下来是文件的属主(owner)
接下来是文件的数组(group)
文件大小(size)默认单位是字节,这里可以用到ls的另一个选项-h,是将文件大小显示成容易读的大小的,就是做了一下单位的转换而已,-lh可以一起用
接下来是时间:时间戳(timestamp,三个:最近一次被访问的时间,最近一次被修改的时间(显示的是这个),最近一次被改变的时间)
访问时间(access):
修改时间(modify):改变了文件的内容
改变时间(change):文件的属性数据也叫元数据(metadata),改变了文件的属性,也就是元数据。
ls –a:显示所有文件,包括隐藏文件,隐藏文件以点开头(-A表示不现实点和点点)
.表示当前目录
..表示父目录
ls –d:显示目录自身属性
ls –ld /root 显示root自身属性
对于人来说,我们记忆文件名可能方便一些,但是对于机器来说,它最擅长处理的应该是数字,所以对于每一个文件来说都有一个唯一的数字来标识这个文件,叫做文件的结点(index node,简称inode)要想显示文件的号码,就用ls 的-i选项,这个选项至关重要。
ls –r:逆序显示文件
ls –R:递归(recursive)显示文件,【注意】递归的方式是非常占内存的,尤其是文件很多的时候。
cd [目录]
常见用法:cd不加任何参数:回到家目录(用户的主目录或者使用cd ~,如果是管理员,则使用cd ~student进入指定用户的家目录)像刚登陆的时候,一般就在家目录中,在家目录中,是想干嘛就干嘛,用户有所有的操作权限。
cd -:在前一个目录和当前目录来回切换(非常好用的)
内置命令:shell内置的命令
外部命令:外部命令一定是在文件系统某一个路径下有一个与命令名称相应的可执行文件
type是用来显示命令类型的
当我们执行ls命令的时候,并没有说是在哪一个路径下的ls,那它怎么知道是在bin下的呢,像在执行su的时候,同样没说在哪个地方,但是它就是知道,这是为什么?
按道理在使用命令的时候是要给出完整的路径的,但是如果使用每一个命令都要给出全路径的话,那就太坑了,所以系统为了能让用户便捷的在命令提示符下执行命令,它给我们内置了一种机制,这种机制是通过一种所谓的环境变量的方式来实现的。
变量:说白了就是命名的内存空间(起了名字的内存空间),然后就可以向这个起了名字的内存空间中放数据了,放数据的过程就称之为变量赋值,比如说定义一个变量:NAME=Jerry;表示在内存中开辟了一段空间,起名叫NAME,空间中放的数据是Jerry。为什么说叫变量了,就是说可以改改里面的值,比如说NAME = Tom。变量只在当前程序中有用。
堆(heap):
栈(stack):
环境变量:在windows里面,同一个计算机里面两个用户的桌面可能不一样,主题也可能不一样,那么这些信息的内容都保存在哪里呢?在哪里进行定义呢?肯定是在配置文件里面进行配置的,里面就是有某一个变量等于什么,然后才会不一样。环境变量就是用于定义当前用户的工作环境的,指定工作环境属性的,我们可以定义工作主题跟别人不一样等等。无论是哪一种shell都有自己的环境变量的。
其中:
HOSTNAME:主机名
TERM:终端类型
SHELL:表示使用的shell程序是什么
PATH:就是一堆使用冒号隔开的路径(次序也很关键),当我们执行命令的时候,系统就会按次序从这些指定路径下一个个去找,知道第一次找到为止。但是系统中可能有成千上万个命令,给一个命令要执行都去找一下,那效率还是很低的,所以系统就有一个缓存,专门来缓存刚执行过的命令
hits:表示使用次数,后面是命令的路径,在缓存中记录下了此前使用的所有命令的路径,后面每一次再用的时候都先找缓存,在计算机发展史上有一句话叫hash is the king:缓存为为王,各个系统都有缓存的,后面再用的时候,先看看缓存中有没有,缓存是一个hash列表,是一个键值数据库,在键值库中查找的时间复杂度是O(1)的,非常快。缓存是实现系统加速的,非常重要,后面会经常强调!!!
所有命令,如果不给全路径,那么在PATH中就一定有相应的路径,否则无法执行。
builtin:内置(内建)命令
linux的时间管理机制:在系统中有一个现象就是当我们的系统关机了,下次开机时间仍然是正确的,这是为什么呢?我们怎么去衡量时间的?时间是个什么东西?在思维空间里面就是加入了一个时间轴。
rtc(real time clock):这是主板上的时间,也就是硬件时间,每一次系统开机的时候,都是从这里读取时间,作为系统时间,在windows系统中,一般在时间的处理上,都会让设置一个时间服务器的,叫做ntp(网络时间协议),可以做一台主机,这台主机上的时间非常准,然后其他的机器同步这台机器上的时间就能保证它的时间是准确的,但是当开机时系统读取rtc时间成功了,就不会通过ntp获取时间,然后系统会通过软件模拟震荡计量时间,但是跟硬件时间可能会不一致,不排除这种可能。
hwclock(hardware clock:硬件时间)
date不仅可以用显示时间,还能修改时间:
0、首先通过命令查看下命令是属于外部命令还是内部命令:
type COMMAND
内部命令:
help COMMAND
但是help ls就没用了
外部命令:对于外部命令来说大多都有一个长选项,--help
COMMAND –help:获得帮助信息
无论是外部命令还是内部命令都可以通过手册(manual)来查看命令的帮助文档:man
man COMMAND
像这些帮助文档在linux中通常就是文本文档,但是这个文档是压缩存放的,所以当我们使用man ls的时候,就打开这个手册了。
【手册说明】:
SYNOPSIS:使用格式说明
DESCRIPTION:使用描述
OPTIONS:各种选项
当man一下内部命令的时候,比如说man一下cd,那么现实的是bash的帮助信息
所以说内部命令很少man去查看,使用help COMMAND是最简洁的。
man read
man 2 read:man后面是可以跟数字的,即显示第几章节的信息,如果不给这个数字的话,就1、2、3……往后排,第一次出现在哪个章节就显示哪个章节的内容,如果多个章节中都有,就需要自己去指定章节了,那么怎么知道命令在哪些章节中有呢?有一个命令:
whatis COMMAND:显示命令的简单介绍和命令存在于哪些章节。
上面的截图就说明了read在第一、二章节中都有,1p、2p就不用管他,print的信息。
【注】如果帮助信息中出现乱码:那么就是语言问题,修改语言:export LANG=en
并非所有的命令都有库调用,只有库才有库调用,如果一个命令和库的名字一样的话,才会同时出现。比如说read命令
设备文件:就是在/dev目录下,像什么块设备、字符设备什么的,设备文件是一个比较特殊的文件,在磁盘的数据区域上是没有存储任何内容,只是作为设备的访问入口存在的,不是一个真正的文件,所以称之为特殊文件
例如:man 4 tty
很多的命令为了定义它的执行特性,我们可以使用选项,那有些命令,它的选项可能不需要用户每次都指定,或者希望这个命令开机就自动启动的,比如说ls命令,我们希望开机就执行以下ls命令,并且给它一个选项。对于非常复杂的执行文件,它通常都有一个配置文件的文件,在这个配置文件中保存了以往可以通过选项指定的程序的执行特性或者执行属性,所以这个配置文件当中都是类似于变量一样,都是***=***的这种方式来定义这个程序的执行属性和特征,但是这个命令的文件到底怎么使用?支持哪些选项,每个选项支持什么样的取值?这些都需要额外定义的。比如:passwd命令,这是用来改用户密码的,那么改完用户密码之后存在什么地方?用户的相关属性保存在什么地方?其实跟用户账号相关的属性有两个文件一个在/etc/shadow一个叫/etc/passwd所以这个文件是有格式的
都是冒号隔开的多个段,man passwd显示的是命令的帮助,如下图:
那么如果要显示这个文件当中,每一个冒号隔开的每一段是什么意思,就可以用man 5 passwd
所以第五章节文件格式就是解释某一个命令对于的配置文件的语法的
【格式说明】:
[]:可省略的
<>:表示必须给出内容非可选
…:表示可以出现多次
|:表示多选一
{}:分组,没有特殊意义
MAN中每个字段的含义:
NAME:命令名称及功能简要说明
SYNOPSIS:用法说明,包括可用选项
DESCRIPTION:命令功能的详尽说明,包括每一个选项的意义,可能有些命令将一些选项单独抽出来OPTIONS:说明一个选项的意义
FILES:此命令相关的配置文件
BUGS:报告BUG给谁的
EXAMPLES:使用实例,有的命令有,有的没有
SEE ALSO:另外参照
【man翻屏】:
向后翻一屏:space(空格键)
向前翻一屏:b键
向后翻一行:enter键
向前翻一行:k键
如果想明确的查找某一个说明:搜索
/keyword:自前向后搜索
n:下一个
N:前一个
?keyword:向前搜索
n:上一个
N:后一个
q:退出
date加上一个选项后,后面还有一个+format,format在后面是有说明的:
date –u 时间:修改时间,注意格式:
月日小时分钟[四位的年|两位的年].秒
例如:date 0226104913.30
format格式的使用
%D:显示日期,格式是:MMDDYY
date +%D
date练习:
仅显示年(带提示的显示方法)
换行显示:
显示小时/分钟/秒:
显示年月日的方法:
显示小时/分钟
【记住】一天86400秒
hwclock –w 将系统时间同步到硬件时间
hwclock –s 读取硬件时间到系统中
hwclock命令:默认情况下是显示硬件时间的
-w:将系统时间写到硬件时钟,有对应的长选项
-s:将硬件时间写到硬件时间,有对应的长选项
-r:读取时间
【注意】在后面配置系统的时候,操作系统时钟是非常常见的操作,务必要记住
【补充,只需了解】在线手册获取帮助:
info COMMAND:主要是详细的讲解命令的发展历程,也会讲解下命令的使用方法。但是用的其实不是很多,只能算是man的补充
例如:info ls,在查看的时候所支持的操作跟man类似
【/usr/share/doc路径】文档路径
大多数重要命令都有相关的说明文档,就是在这个路径下,但是这些文档一般不需要我们着重去关注,只需要有这个东西就可以了,当常识了解
当然可以cal某一年的日历,或者cal某一年的某一月等
type echo查看
echo是内部命令
内部命令使用man来查看帮助信息:
如果想要换行显示,从帮助信息中可以看出,使用\n但是从结果中可以看出,原样输出了,原因是没有启用反斜杠的作用,加一个-e选项即可
-n:不输出换行符
例如:
printf同样是内部命令
用来查看文件类型的命令:
ELF:可执行文件的存储格式,表示可执行的,可连接的文件类型,这是在linux上常见的可执行的二进制的格式,在windows下是叫PE格式,这个了解一下。
Linux目录是一个倒置的树状结构,通过层次性的方式来组织管理整个系统上的文件,而这本身是通过文件系统来进行的。文件系统是内核的主要功能之一,其功能就是要实现本机上的某一个分区上的文件管理的,最后要记得文件系统一般而言对磁盘来说通常是指以分区为单位进行标识的,但是在整个系统上,所以的文件系统都必须同属于整个系统之一的一个东西,就是所说的根成为rootfs:根文件系统。
因为Linux的发行版众多,所以Linux标准委员会颁布了FHS(文件系统层级标准)来约束每种Linux发行版的文件系统层级目录格式,规定了一个Linux发行版必须创建哪些目录来存放哪些文件,这些都是指定好了的。
使用ls /就可以看到根下的目录结构
一定要记住的根下的重要目录:
/boot
在红帽6里面vmlinuz-2.6.18-128.el5依然存在,但是initrd-2.6.18-128.el5.img该名了,但是功能是一样的,这两个文件其实是操作系统启动所要用到的内核以及暂时性的小Linux系统 ,注意这个initrd-2.6.18-128el5.img是一个映像文件,类似虚拟机创建的文件系统一样,像一个假的硬盘,甚至还可以对它进行分区等等,实际上这里只有一个分区,它里面具有了一个传统意义上Linux具有的很多资源目录,当然主要目的当Linux启动的时候后面详细介绍。
系统启动相关的文件,如内核、initrd(initialized ram disk),以及grub(boot loader)
设备文件,前面起到了Linux的重要哲学思想之一就是一切皆文件,因此所有的硬件设备也被识别为一个个文件,比如说我们的DVD光盘
像这种颜色的文件都是连接文件
在windows下面就理解成快捷方式
后面引用设备的时候也都是在这里去找
设备文件:
块设备:随机设备,可以实现随机访问的设备像硬盘,我们存了三个文件A、B、C文件,如果说我们要访问C文件,非要经过A、B文件就麻烦了,所以说我们可以直接访问C文件而不用经过A、B文件。 它的访问是按照组织成对应的数据块进行访问的,首先数据都被分为一个一个块的,所以又被成为块设备。
字符设备:线性设备,完成线性访问,有次序的,像键盘,敲个ABC,如果显示成BCA就麻烦了,通常是按照一个字符一个字符输入的,它是按字符为单位的,显示器是线性设备,在显示之前还是先在缓存中按序存储好了,再显示的。
像这类文件是非常独特的,颜色上独特,文件类型也比较独特,还有第五列的内容的含义也很独特,本来应该显示文件大小的,但是这里没有大小,直接存储为元数据,没有数据,作为数据的访问入口存在的。这两个数字是设备的设备号,或者是硬件的设备号。
设备号:主设备号和次设备号
【注意】:一个设备只有有设备文件才能被Linux访问的,以后但凡是要在Linux上接入一个新设备比如说一个U盘,就必须在dev目录下创建一个设备文件,当然在大多数情况下,系统是会自动完成的。
【说明】配置文件的主要存放路径,纯文本文件
系统上大多数程序或者服务程序的配置文件都在这个目录下,或这个目录下创建一个子目录下。像/etc/passwd文件
【说明】家目录
每一个用户都有自己的家目录,需要注意,用户的家目录是不能重复的,所以用户的家目录通常默认为home下有一个跟用户名同名的目录:/home/USERNAME比如说:
注意root用户非常特殊,它的家目录不在/home目录下,而直接在根目录下,并且它的命令就叫root,在传统的Unix系统上,root用户是没有家目录的,因为root用户是从来都不需要登陆系统的,事实上在Linux上也遵循此法则,一般情况下,我们现在是学习,为了使用方便,在工作的时候,一定不要直接拿root用户登陆,root用户有所有权限,是非常危险的,随便一个误操作都可能是致命的。在实际生产中,一般是使用普通用户登录,当要使用到管理类的操作时才会去切换到root用户。
【说明】管理员家目录
【说明】库文件及内核模块文件
/lib/modules:内核模块文件
库文件有两类:
静态库:Linux下.a文件
动态库:windows下:.dll Linux下:.so(shared object)共享对象
动态和静态的区别:库就是某些被封装好的某些功能,不需要程序员写了,共享库的好处就是如果第一个程序使用到了某一个共享库,已经加载到了内存了,第二个程序如果也要使用的话,就不需要再次加载,大大的节约内存空间;静态库并非如此,静态库直接连接到程序的地址空间中去的,作为程序的一部分去运行的,所以静态方式适合于程序单个文件管理,比如要将一个程序从一个Linux主机移到另一个Linux主机,如果使用的静态编译方式,就是说使用了静态库,那么就只需要将文件从A主机复制到B主机就能直接运行的,但是如果要使用动态链接库的话,就是说它自己的运行还是要依赖库的,那就意味着我们如果将一个使用了动态库的程序移到另一个主机上,就要保证另一个主机上要有相应的共享对象才行。
像这些文件都是绿色的,也就是说都是有可执行权限的,之所以没有显示可执行格式,是因为库没有程序执行入口,只能被调用。
【说明】实现丢失和重新找回的作用的
把某个设备跟当前文件系统上的某一个目录建立关联关系就叫挂载的过程,比如说:像我们并不是将一个CD放到光驱,然后就可以进去/dev/cdrom访问CD中的文件的。而是需要将这个文件和文件系统中的某个文件相关联才行,而/media和/mnt就是这么两个常用来给别的设备关联的两个目录
并没有严格的规定,只是习惯性的这么去做而已
【说明】可选的目录(可有可无)早期通常是用来安装第三方程序的,但现在约定俗成已经不往这里放了。
【说明】伪文件系统,没有任何内容
本身是空的,但是当系统运行起来之后就不空了,如果系统不启动,打开这个目录是空的,这里面显示的文件都是内核的映射文件,所以这里边大多数文件都是内核中很多的可调参数或者内核工作的统计数据,我们想要看一看内核当前它的工作属性,像网卡,网卡是一个设备,设备要想被访问,只有内核去访问了,那么网卡究竟接受了多少个数据包,发送了多少个数据包,这些统计数据都在这里面,如果想改变内核的工作属性,通常是通过改变这个目录下的某个文件来完成的。像后面会讲到的系统调优很多都是跟这个目录相关的。还有系统性能数据的监控也是跟这个目录相关。这是非常重要的目录,但是也是最难理解的目录。
【说明】伪文件系统,
block:块设备
bus:总线
firmware:固件
fs:文件系统
kernel:内核
module:模块
power:电源相关的
同proc。跟硬件设备相关的属性映射文件,跟内核也是相关的,只不过把它独立出来了当作一个文件系统来使用,通常用来实现硬件设备管理的,尤其是像硬盘这样的存储设备,还是那句话,既然跟内核相关,那么我们的很多调优工作就要涉及到这个了,比如我们修改磁盘调度队列或者磁盘I/O调度队列的时候,都是在这个里面进行修改的。还是那句话,关机后这个目录也是空的,它里面的内容也是映射出来的信息而已
【说明】临时文件
很多用户登录到系统中来都要存储临时文件的,所以说一些公共的临时文件可以被其他用户查看到的临时文件都是放在这个目录下的。像临时文件就是说不需要永久性存储的,所以如果一个月这个目录没有被访问过的话,会被自动清除的,这是系统上定义的一些脚本完成的计划任务,而且这个目录还非常独特,每一个用户在里面可以创建文件,谁都有权限,但是每个人却只能删自己的文件,删不了别人的文件。从ls –ld命令就可以看出,它不同于其他目录,它的底色是绿色的,权限也非常独特,是t。
【说明】可变化的文件,刚装完系统这个目录很小,当系统运行一段时间后,这个目录就会越来越大了。里面有很多子目录,有一些是比较关键的子目录,比如说像cache(缓存),lock(锁文件),log(日志),mail(用户的邮件转存位置),run(Linux中每一个进程运行起来后都有一个进程号码,而许多服务需要存储的进程号码在一个文件中,这文件就在run目录下,而且通常是.pid,这叫进程ID号。
/var下也有tmp目录,是有一个临时文件目录
/bin:binary
存放可执行文件,这里面放的用户命令
/sbin:放的管理命令
/usr:是universal shared read-only全局共享只读文件,也是非常重要的目录,里面放的只读文件,在/usr下面也有一些很独特的文件,像
/usr/bin
/usr/sbin
/usr/lib
【重要】这些目录跟根目录下的那些有什么区别呢?
可以理解为:根目录下的那些像/bin和/sbin是跟系统自身启动相关的命令或可执行程序,而/usr目录下的则是系统启动起来之后为了提供一些基本功能的所应该具备的一些命令或者可执行程序,所以说一个是跟系统启动相关的一个是跟系统正常运行提供基本功能相关的。当然只是方便认识所做的分类,当然如果/usr目录下的bin和sbin所依赖的库不是公共的库,那么它的库就必须放在/usr/lib目录下。
/usr/local:
/usr/local/bin
/usr/local/sbin
/usr/local/lib
这是第三方软件的安装路径,它底下甚至还有etc专门用来存储配置文件的。
一般来讲/bin,/sbin,/lib;/usr/bin,/usr/sbin,/usr/lib对一个操作系统来说是必须的,而/usr/local下的那些并非必须的,跟系统运行不大相关。
所以/bin和/sbin下放程序,/lib下放的库,程序的运行可能依赖于/lib下的库,而且有的程序可能用到配置文件,就在/etc目录下,这就是它们的关联关系。以上就是linux下的关键路径了,一定要熟练掌握,懂了这个之后,完全可以拿一块硬盘,或U盘,在里面创建这么几个目录,拷贝几个文件进来,然后这个U盘就可以启动起来了,就这么简单。不需要其他额外的东西,因为Linux没有注册表的概念。
Linux是严格区分文件大小写的,还要记住以下几个规则:
相对路径:相对与当前路径去查找文件
绝对路径:由根开始的
具体是哪一种方式好,就要依情况来说了
文件管理:(最关键)
创建文件
删除文件
查看文件
编辑文件
查找文件
目录管理:
列出目录类容
显示目录
切换目录
创建目录
删除目录
执行程序:
设备管理:
创建设备文件
删除设备文件
分配设备文件标号
挂在设备
访问设备
给设备提供驱动程序
软件管理:
还是体现为文件管理
进程管理:
进程都表现为文件
进程数据查看、统计
网络管理:
从上面可以看出,linux的核心思想——一切皆文件,所以文件管理是至关重要的,而文件又都是放在目录下的,所以先了解目录:
【基本】前面提到了的三个命令ls、cd、pwd
【说明】创建空目录,注意在不特殊指定的情况下,所给的文件路径的最后一个点才是我们要创建的目录。
例如:mkdir x mkdir x/y mkdir x/y/z
-p:会一次性创建完不存的目录
mkdir –p /root/m/n/q
-v:verbose详细信息
将-pv一起使用:
在Linux中,如果说执行一个命令没有返回什么信息,那么这就是最好的信息,这是Linux的重要哲学思想。当执行命令显示一堆信息的时候,通常表示命令执行的有问题。
假设有这么一个需求:
希望创建:/mnt/test/x/m,y,如果一个命令搞定?
mkdir –pv /mnt/test/x/m /mnt/test/y
改进:mkdir –pv /mnt/test/{x/m,y}
【难题】:一个命令在/mnt/test2目录下创建:a_b,a_c,d_b,d_c4个目录
波浪线展开:~USERNAME
【说明】删除空目录(remove directory)
这个命令不太好用,用的不多其实
-p:只能删除一脉单传的目录,如果有上万个目录,就纠结了
#touch创建文件,但是这算是歪打正着,本身不是用来创建文件的,是用来修改文件的时间戳的。黑客用的比较多
前面说过一个文件有三个时间戳
可以看到,touch了一下之后,文件的时间戳都变了
-c:不创建任何文件
-a:只改变访问时间
可以看到文件属性也改了change的时间戳就变了。
-m:只改变修改时间
如果我偷偷的溜进了别人的电脑在一个文件中加了点东西,然后想通过该文件的时间戳,弄成想什么都没发生一样,该如何修改呢?
-t
touch –m -t 201212121212 a,这样就将最近一次的修改时间改了
【常识】linux的文本编辑器:
word不是一个文本编辑器,是字处理器,因为除了文本它还存储了其他信息,文本是指的纯文本,不含任何其他信息,像字体大小、颜色等。
ASCII码:美国标准信息交换码,假如说现在有128个字符需要存储下来,怎么存?大家知道计算机只能存储二进制的信息,如果存储128个不相同的字符,如何存?第一个叫0,第二个叫1,第三个叫10等,那么一共就需要使用7位二进制就能表示128种变化了,计算机存储数据最小的单位是字节,一个字节是8位,因此虽然是128个不同的字符,但是还是要使用8位,不能再小了,ASCII就是靠这些基本的二进制的变化来表示的不同字符,是一种标准。
【补充】汉子的表示方式:
中国的汉字是非常多的,常用的几千个,可以实现的汉字有十多万个,为了表示大多数不同的汉字,就需要16位,也就是能表示65535个汉字了,两个字节一个汉字。那0000 1001 0000 1110怎么去理解,是两个ASCII码还是一个汉字,怎么理解就取决于语言字符集,你想让它解释成什么样的字符,那么就在这个数据上套上一个字符集,或者叫做转义器的这么一个东西,我把它理解成ASCII码,那就肯定有一个ASCII的转换器,相对应的将它翻译成对应字符,汉字也是一个道理,如果拿到的是汉字的转换器的话,肯定就是转换成汉字了,到底是转换成什么,就需要一个标准了,常用的有GB18030,GBK,GB2312,当用不同的编码机制翻译的时候,解释的是不一样的,然后还有一个柔和了几乎所有的字符的Unicode,它基本上包括了所有国家的字符集,方便全球化。实际上计算机只能理解0、1,之所以能识别其他的是靠软件让它转义达到目的的。
所谓的文本编辑器:只编辑ASCII码的
【说明】简单的文本编辑器
具体的功能查看下面的提示:^表示ctrl
【说明】删除文件
可以看到rm是rm –i的别名
-i:交互式(为了避免误操作的)
如果就说想用它原本的命令就用\rm a,如果没有别名这样写是没有意义的,比如说ls默认是有颜色的,如果\ls的话,是没有任何颜色的
-f:强行删除(force)明确指定不要任何提示,直接删除
-r:recursive(递归删除)用来删除目录
-rf:递归删除目录,不用提示
rm –rf /:删除根目录及其下面的所有文件(这个命令一来系统就没了)
【注】对于管理来说,这个命令太危险了,一旦不确认一下,后果不堪设想!!!
别名的概念:(后面会详细的说的)
【说明】显示文件或文件的状态信息:
最后的三行就是那三个时间戳
【说明】查看文件系统树
tree x
【用法】cp SRC DEST
需求1:将一个文件复制成多份文件放在不同的目录下
cp file1 file2 file3 只有file3是目标
对于cp命令来讲,只有最后一个是目标,此前的所有都是源,也就是说它是不允许一个源多个目标的,也允许出现一个目的地,所以说不能同时将多个文件合并成一个文件,因此可以复制一个文件到一个文件,或者多个文件到一个目录。
比如:
cp /etc/passwd /tmp
cp /etc/passwd /tmp/test 判断:如果test是不是存在,如果不存在,就复制重命名为test,如果test存在,再判断test是文件还是目录,如果是文件就提示是否覆盖,如果是目录,直接复制进去。
cp /etc/passwd /etc/issue /etc/inittab /tmp 【注意】多个文件复制,目标必须是目录
复制目录:
-r或-R:递归复制一个目录及其里面所有的所有文件
其他的命令同样是存在的:
-i:交互式复制
-f:强制的复制
-p:
在复制的时候保留原文件的属主、属组、时间戳
-a:保持连接本身,保持所有的源文件属性,也可以复制目录
归档复制,是备份常用的一种方法
【难题】解释:cp /etc/{passwd,inittab,rc.d/rc.sysinit} /tmp/
这里复制的实际上是三个文件,花括号的展开机制,在文件路径的操作当中很多地方都可以使用。
【说明】移动文件,移动方式基本上和cp是一模一样的。
mv SRC DEST,还是那么几个相关的问题。
例如:mv /tmp/hello /var/tmp/
mv /tmp/hello/ /var/tmp/abc abc不存在意味着重命名,且abc为目录,如果abc存在但是是一个文件,那么会报错:不能拿一个目录去覆盖一个非目录
重要作用:给文件改名字
mv abc mn 目录相同,文件名不同就是重命名了
【注意】mv操作目录不需要加选项,从别名上可以看到,mv同样是mv –i的别名
新用法:mv –t DEST SRC
用法如下:
源一个,目的地没有说明是文件还是目录,但是当源有多个的时候,目的地必须是目录,还可以使用-d选项,后面直接跟目录,这是在创建目录例如:
install –d /tmp/{install.1,install.2} 这就是说在tmp目录下创建了两个目录
install /etc/passwd /var/tmp/install.file1 复制文件,复制过去了之后是有执行权限的,这个要注意。
可以指定权限:
-m:指定mode
-o:指定文件所属
5.3、文本处理
相关命令:cat、more、less、head、tail、cut、uniq、grep
管道和重定向:> < >> <<
用户、组、权限
正则表达式
bash及其特性
du命令(自学):
-s:
-h:
例子:
read命令(自学):
从命令type查看read的类型可以看出,read是内部命令
那么使用help查看read的帮助信息:
描述:
read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量,用 IFS(内部字段分隔符)变量中的字符作为分隔符。VariableName 参数指定 shell 变量的名称,shell 变量获取输入行一个字段的值。由VariableName 参数指定的第一个 shell 变量指定给每一个字段的值,由 VariableName 参数指定的第二个 shell 变量指定给第二个字段的值,以此类推,直到最后一个字段。如果标准输入行的字段比相应的由 VariableName 参数指定的 shell 变量的个数多,把全部余下的字段的值赋给指定的最后的 shell 变量。如果比 shell 变量的个数少,则剩余的 shell 变量被设置为空字符串。
【注意】: 如果省略了 VariableName 参数,变量 REPLY 用作缺省变量名。
例如:
回顾总结:
目录管理:ls、cd、pwd、mkdir、rmdir、tree
文件管理:touch、stat、file(查看文件内容类型的)、rm、cp、mv、nano
日期时间:date、clock、hwclock、cal
查看文本:cat、tac、more、less、head、tail
cat命令:
【说明】连接并显示给定文件的内容
cat /etc/issue
cat /etc/issue /etc/fstab
常用选项:
-n:显示行号
-E:显示每一行的行结束符,对于linux而言,文本文件的行结束符是$,windows的是$加回车符,所以从linux文本中拷贝到windows中会通通显示一行,在windows中的文本编辑器拷贝到linux中可能会出问题,但是notepad++就很好用,可以指定不同的结束符。
tac命令:
【说明】从尾部到首部显示命令
常用技巧:
ctrl+c可以立即终止当前命令
应用小技巧:当我们在命令提示符下敲了一个命令,敲到一半的时候,突然不想执行了,这时不需要删,直接ctrl+c即可
more、less命令
【说明】分屏显示文本内容
less命令更加常用:
用法跟man一样,man中用到的,在less一样支持,man就是用less打开查看的,所以参考man命令,less翻到最后是不会退出的,只有敲q才会退出
head/tail命令
【说明】查看文件的前n行/查看文件的后n行,默认n=10,
-n:直线显示多少行,直接-2也可以,但在unix中是不支持的,这个要注意
tail跟head差不多的一个前一个后,别的没什么特别的区别
tail命令特殊的选项:
-f:查看一个文件后并不退出,等着只要其他进程一往尾部写内容,就立马显示出来,这个特性非常有用,在服务的监控上用的非常多。
文本处理相关命令:cut、join(用的不多)、sed(功能强大,但是相当难)、awk(报告生成命令,这个更难)
cut命令:
【说明】文本剪切
【补充】database数据库:
需求:现在需要查看这个文件里面的第一列,该如何做?这就是cut命令存在的意义了。
-d:指定分隔符
cut –d: -f1 /etc/passwd 显示第一个字段
或者:
cut –d : -f1 /etc/passwd
-f:fields显示的字段:-f 1,3显示第一个和第三个,如果-f 1-3则是连续表示,显示1,2,3个字段
实现文本排序的命令:
sort命令:
【说明】跟cut一样,都是不影响源文件的内容的,只是改变了输出文件的样子。
默认排序是根据升序进行的,ASCII码的顺序进行的。
例如:
sort /etc/fstab
-n 按照数值的大小排序,而不是按照ASCII表中的顺序排序的
-r 逆序排,当然这可以跟-n一起使用
sort跟cut有点相像,可以指定分隔符,然后按照某个字段进行排序
-t:字段分割符
-k:以哪个字段为关键字进行排序
例如:sort –t: -k3 -n /etc/passwd
-u:排序后让相同的内容只显示一次
-f:排序的时候忽略字符大小写
uniq命令:
【说明】忽略相邻的重复行
-d:只显示重复的行
-D:重复的行都显示
-c:显示文件中行重复的次数
文本统计类的命令
wc(word count)命令:
【说明】统计一个文件中
例如:wc /etc/fstab
行单词数字节数
-l:只显示行
-c:显示字节数
-m:字符数
-w:单词数
tr命令:字符处理命令
【说明】转换或删除字符
用法:tr [option]… SET1 [SET2]
例如:tr ‘ab’ ‘AB’ 然后就等着输入内容了,输入的ab转换为大写的AB
当然不是就等着让我们输入的,还可以替换文件中的内容
例如:tr ‘ab’ ‘AB’ < /etc/passwd 使用输出重定向
tr ‘a-z’ ‘A-Z’ < /etc/passwd
tr用来删除字符
-d:删除出现在字符集中的所有字符(逐个字符进行处理的,而不是处理单词的)
例如:tr –d ‘ab’,这是等着标准输入的,当然也可以使用输入重定向了来删除文件中的字符
bash及其特性:
一个操作系统当中跟用户最接近的就是shell了。
shell:外壳
GUI:Gnome、KDE、Xfce
CLI:shell、bash(遵循开源协定的,所以默认的shell都是bash)、csh、ksh(商业化的商品)、tcsh、ksh克隆版(开源的)、zsh
root用户、student用户,两个用户默认的都是bash程序,但是程序只可能有一个,但启动起来进程是有多个的,进程可以理解为程序的副本,每一个用户登录,都会打开一个bash,三个进程,三个进程之间各不相干。linux还允许一个用户登录多次,而且还互相之间互不相干。
进程:在每个进程看来,在当前主机看来,当前主机上只存在内核和当前进程。进程是程序的副本,进程还是程序执行的实例,进程是有生命周期的,由内核管理。
用户的工作环境:
bash:不同用户即便都是使用的bash,但是他们的工作环境可以各不相同,大部分默认的设定都是一样的。
#
$
shell,子shell:可以在shell中开一个shell,这就是为了说明每个进程是不能意识到其他进程的存在的,即使是父子关系
bash的特性:
无论是哪一种shell都支持用户对自己的环境做装饰,所以shell为了便于用户使用计算机,也提供了很多好的特性:
命令历史(上下箭头)、命令补全
管道、重定向
命令别名
命令行编辑
命令行展开
文件名通配
变量使用
编程
命令行编辑:
光标跳转:
Ctrl+a:跳到命令行首
Ctrl+e:跳到命令行尾
Ctrl+u: 删除光标至命令行首的内容
Ctrl+k: 删除光标至命令行尾的内容
Ctrl+l: 清屏
Ctrl+左右箭头可以一次跳一个单词,但是只在模拟终端中支持
命令历史:
bash会自动记录过去曾经执行过的命令,会将其保存在内存的一个缓存区域当中,还有一个内置命令:history
使用history可以查看历史命令,当然history还有管理功能,比如说我们溜进了别人的电脑,执行了一些命令,然后不想让别人知道,那么就可以用history的管理功能。
-c:清空命令历史
-d OFFSET [n]:删除指定范围的命令
例:history –d 500 删除第500这个命令
history –d 500 3 删除500、501、502这三个命令历史
一旦这个shell进程结束,命令缓存就没了,如果下一次开机还想用的话,就可以在用户的家目录下的隐藏文件中去看.bash_history,这个文件就是保存用户所有执行过的命令的。
-w:将缓存去中的命令历史至历史文件
bash最多能保存1000条,默认的
命令历史的使用技巧:
如果想执行命令历史中的第n条历史
!n:执行命令历史中的第n条命令
!-n:执行命令历史中的倒数第n条命令
!441
!!:执行上一条命令
!string:执行命令历史中最近一个以指定字符串开头的命令,字符串多长就要注意了,不然可能不是我们想要的结果
!$:引用上一个命令的最后一个参数,Esc,. :按下esc再按点也行(很好用);
应用场景:当我们cat查看了一个文本,现在想编辑一下,用vi+上一个命令的最后一个参数
命令补全:(在PATH环境变量下搜索补全的)
PATH:
敲tab键自动补全的
路径补全:从打头路径下进行补全的
命令别名:
alias CMDALIAS=‘COMMAND [options]’有空格最好用引号引起来
【说明】给某个命令起别名,别名的有效范围为当前的shell进程
如果想让别名永久有效,那么就修改配置文件即可
例如:alias cls = clear
alias显示系统所定义的所有别名
像在/etc/sysconfig/network-scripts/下有很多网络配置相关的文件,经常需要打开,所以可以定义一个别名:alias cdnet=’cd /etc/sysconfig/network-scripts/’
如果经常使用的别名都可以使用别名提高效率
撤销别名:unalias CMDALIAS
例如:unalias cls
如果不想使用别名,想直接使用命令本身的话,就在命令前面加一个/即可
命令替换:$(COMMAND),反引号:`COMMAND`(注意是反引号,是在波浪线的那个键)
bash支持的引号:
` `:反引号
“ ”:若引用,可以实现变量替换
‘ ‘:强引用,不完成变量替换
【说明】把命令中某个子命令替换成其执行结果的过程
例如:显示当前目录
echo “the current directory is $(pwd).”
例如:创建一个文件,文件名是当前时间,这个时候使用命令替换是最好的做法了
touch ./file-$(date +%F-%H-%M-%S).txt
文件名通配机制:globbing
其实就是命令行展开的一种机制
*:可以用于匹配任意长度的任意字符
?:匹配任意单个字符
[]:匹配指定范围内的任意单个字符[abc] [a-m] [a-z] [A-z] [0-9] [a-zA-Z]大小写都包括了
[^]:匹配指定范围之外的任意单个字符,像以非数字开头的、以非字母开头的文件
[^0-9]
[[:space:]]表示所有的空白字符
[[:punct:]]表示所有的标点符号的
[[:lower:]]表示小写字母
[[:upper:]]表示所有的大写字母
[[:alpha:]]表示所有的大小写字母
[[:digit:]]表示数字
[[:alnum:]]表示数字和大小写字母
使用命令:man 7 glob就可以查看命令帮助了
创建测试环境:touch a123 abc ab123 xyz x12 xyz123
显示以一个字母开头,后面跟着数字的文件名:ls [a-zA-Z][0-9]
以a开头,后面跟任意字符:ls a*
显示以字母a开头,以数字三结尾的文件:ls a*3
以字母开头,后面跟着任意数字的文件:[a-zA-Z]*
以a开头,后面跟了一个数字的,又跟了任意字符的:
以任意一个字符(字母、数字均可)后面跟了一个y,又跟了其他任意字符的:ls ?y*
显示文件名中字母开头中间可能有其他字符包括空白字符的文件:[[:alpha:]]*[[:space:]]*[[:alpha:]]
用户:标识符
用户组:是一个逻辑概念,也是一个标识符
进程的安全上下文(security context)
任何时候用户使用计算机,无非就是发起了一个进程,因此进程一定是代表用户来运行的,进程能访问哪些文件取决于用户对文件的权限。
权限:
r,w,x
对于文件来说:
r:可读,可以使用类似cat等命令查看文件内容
w:可写,可以编辑或删除此文件
x:可执行,可以在命令提示符下当作命令提交给内核运行
对于目录来说:
r:可以对此目录执行ls以列出所有文件
w:可以在此目录中创建文件
x:表示可以使用cd切换进此目录,也可以使用ls –l查看内部文件的详细信息(一般都有)
rwx:
r--:只读
r-x:读和执行
---:无权限
对于某一类用户,权限的组合:
000 0 ---:无权限
001 1 --x:执行
010 2 -w-:写
011 3 -wx:写和执行
100 4 r--:只读
101 5 r-x:读和执行
110 6 rw-:读写
111 7 rwx:读和执行
常见的权限组合:
755:rwxr-xr-x
640:rw-r-----
660:rw-rw----
775:rwxrwxr-x
用户:
对于计算机而言,识别数字的速度是非常快的,直接就能识别数字,计算机如果要将数字识别成字符串,就需要软件来完成。因此计算机无论是识别用户还是进程都是通过数字来完成的,在计算机中,每个用户都有一个ID来表示某个用户,叫UID,每个组同样有一个ID用来标识这个组,称之为GID。计算机通过查询一个数据库来找到那些数字和用户名的对应关系,在/etc/passwd文件中,就有这样的一个对应关系,当用户登陆系统,就会查这个表。组的对应关系就在/etc/group下定义的有。
当用户登录系统之后,系统就会帮用户启动一个shell,如果用户没有指定,则会启用一个默认的shell,这就是在用户信息库中定义的,还是/etc/passwd文件中,所以这个文件应该是所有用户都能查看的,但是密码就这么放在里面是不安全的,所以在计算机中就有一个影子的概念,所有的密码放在shadow中,所谓的影子口令,这是用户的;组同样也需要密码,在/etc/gshadow文件中,虽然组不需要登陆系统,但是同样需要一个密码,
用户类别:
为了便于用户管理,在红帽用户的管理上,被分为三个类别
管理员:0
普通用户:1-65535
系统用户:1-499
一般用户:500-60000
用户组:
管理员组:
普通组:
系统组:
一般组:
用户组类别:
私有组:创建用户时,如果没有为其指定所属的组,系统会自动为其创建一个跟用户名同名的组
基本组:用户的默认组
附加组,额外组:默认组以外的其他组
对于/etc/passwd文件中的七个字段分别是什么意思?
对于一个命令,我们可以通过whatis查看该命令在man中的哪几个章节中有帮助信息,第五章节就是命令文档中的帮助信息:
account:用户名/登陆名
password:用户密码,如果是x则表示一个占位符,表示密码不在这里,而在另一个文件中存放。
UID:用户的ID号
GID:用户的基本组ID
GECOS:可选的,用户的注释信息
HOME DIR:家目录
SHELL:用户的默认shell,大多数用户是bash
【补充】在/etc/shells文件中有当前系统中所有的可用shell
shadow文件:
/etc/shadow
account:登录名
encrypted password:加密了的密码
头两个$符之间的1表示md5加密方式进行加密的,
如果显示为两个!!,或者*号,则表示用户是锁定的,不能够登陆系统
从1970年1月1号开始到密码上一次修改位置所经过的天数
密码最短使用期限,0表示不做限定
密码最长使用期限
密码
为什么每次新建一个用户都会有相关的默认值?
在/etc/default文件中的定义中说明了
用户管理相关的命令:
useradd ,userdel, usermod passwd chsh chfn finger id,chage
组管理命令:
groupadd groupdel groupmod gpasswd
权限管理:
chown chgrp chmod umask
后记:
学技术的三个阶段:
第一阶段:
昨夜西风凋敝树,独上高楼,望断天涯路
第二阶段:
衣带渐宽终不悔,为伊消得人憔悴
第三阶段:
众里寻他千百度,蓦然回首,那人却在灯火阑珊处