Linux系统中的高速缓存有哪几种

Linux系统使用了几种涉及到高速缓存的内存管理方法。
1   缓冲区高速缓存
缓冲区高速缓存中保存着块设备驱动程序所用到的数据缓冲区。
这些缓冲区的大小固定,一般包括从块设备中读入的和将要写入到块设备中的信息块。块设备一次只能处理大小固定的数据块。硬盘就是块设备中的一种(这里指的是直接写硬盘这种块设备文件,我们平时用的是直接写普通文件,普通文件是一种文件类型,块设备文件也是一种文件类型,所以这里一定要区分清楚块设备和普通文件的区别)。缓冲区高速缓存使用设备标识符和块号作为索引来快速地查找数据块。块设备只通过缓冲区高速缓存进行存取。如果所需要的数据存在于缓冲区高速缓存中,那么就不需要从物理块设备中读取,这样存取的速度就会加快。
 
2   页面高速缓存
页面高速缓存用来加速磁盘中文件镜像和数据的存取。
对于已经作好了磁盘映射的文件,Linux每次读取一页,并将读取的页面存储到页面高速缓存中。
图1 0 - 5显示页面高速缓存由p a g e _ h a s h _ t a b l e组成,p a g e _ h a s h _ t a b l e是一个包含指向m e m _ m a p _ t结构指针的数组。每当从一个内存映射文件中读取一个页面时,页面都要从页面高速缓存中读取。如果页面在高速缓存中,则将一个指向m e m _ ma p _ t的指针返回给页面错误处理程序。否则,页面必须从磁盘上读入到内存中。
如果可能,L i n u x系统将会提前读取文件中的下一个页面,这样,如果文件是顺序执行的,那么下一个页面就已经在内存中了。
随着文件的读入和执行,页面高速缓存也将变得越来越大。不用的页面将被移出高速缓存。
 
3   交换高速缓存
交换文件中只保存那些被修改过的页面。只要在页面被写入到交换文件中后没有被修改过,那么此页面下一次从内存中交换出来时就不用再写入到交换文件中了,因为交换文件中已经有了该页面。这样,该页面就可以简单地扔掉,节省了大量的系统操作。
 
 
4   硬件高速缓存
一个常用的硬件高速缓存是在处理器中,它一般保存着页面表的入口。
 
内核交换守护进程kswapd
当物理内存变少时,L i n u x内存管理必须释放物理内存页。此任务由内核中的交换守护进程( k s w a p d )完成。
交换守护进程是一个内核线程。内核线程是无需使用虚拟内存的进程,它们在物理内存中运行于内核方式下。交换守护进程还有一个重要的任务是保证系统中有足够的空闲内存。
交换守护进程是由内核的初始化进程启动的,并一直等候直到内核交换计时器周期性截止。每当计时器截止时,交换守护进程都要检查系统中的空闲的页面数是否太少。它使用两个变量free_pages_high 和f r e e _ p a g e s _ l o w来决定是否需要释放一些内存。只要空闲的内存数大于f r e e _ p a g e s _ h i g h,交换守护进程就不做任何事,它将再一次进入睡眠状态直到计时器再一次截止。
检查系统中空闲页的目的是使交换守护进程可以计算出需要往交换文件中写入的页面数,此数目保存在n r _ a s y n c _ p a g e s中。
每次有页面排队准备写入到交换文件中时,n r _ a s y n c _ p a g e s的值就会增加,而当写入结束后,n r _ a s y n c _ p a g e s的值就将减少。free_pages_low 和f r e e _ p a g e s _h i g h是在系统启动时设定的,并和系统的物理页面数有关。如果系统中的空闲页面数低于f r e e _ p a g e s _ h i g h,或者甚至低于f r e e _ p a g e s _ l o w,则内核的交换守护进程将用以下三种办法减少正在使用的页面数:
• 减少缓冲区和页面高速缓存的大小。
• 把System V的共享内存页交换出系统内存。
• 交换或扔掉内存页。
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
文将对 Linux™ 程序员可以使用的内存管理技术进行概述,虽然关注的重点是 C 语言,但同样也适用于其他语言。文将为您提供如何管理内存的细节,然后将进一步展示如何手工管理内存,如何使用引用计数或者内存池来半手工地管理内存,以及如何使用垃圾收集自动管理内存。 为什么必须管理内存 内存管理是计算机编程最为基本的领域之一。在很多脚本语言,您不必担心内存是如何管理的,这并不能使得内存管理的重要性有一点点降低。对实际编程来说,理解您的内存管理器的能力与局限性至关重要。在大部分系统语言,比如 C 和 C++,您必须进行内存管理。本文将介绍手工的、半手工的以及自动的内存管理实践的基本概念。 追溯到在 Apple II 上进行汇编语言编程的时代,那时内存管理还不是个大问题。您实际上在运行整个系统系统有多少内存,您就有多少内存。您甚至不必费心思去弄明白它有多少内存,因为每一台机器的内存数量都相同。所以,如果内存需要非常固定,那么您只需要选择一个内存范围并使用它即可。 不过,即使是在这样一个简单的计算机,您也会有问题,尤其是当您不知道程序的每个部分将需要多少内存时。如果您的空间有限,而内存需求是变化的,那么您需要一些方法来满足这些需求: 确定您是否有足够的内存来处理数据。 从可用的内存获取一部分内存。 向可用内存池(pool)返回部分内存,以使其可以由程序的其他部分或者其他程序使用。 实现这些需求的程序库称为 分配程序(allocators),因为它们负责分配和回收内存。程序的动态性越强,内存管理就越重要,您的内存分配程序的选择也就更重要。让我们来了解可用于内存管理的不同方法,它们的好处与不足,以及它们最适用的情形。 回页首 C 风格的内存分配程序 C 编程语言提供了两个函数来满足我们的三个需求: malloc:该函数分配给定的字节数,并返回一个指向它们的指针。如果没有足够的可用内存,那么它返回一个空指针。 free:该函数获得指向由 malloc 分配的内存片段的指针,并将其释放,以便以后的程序或操作系统使用(实际上,一些 malloc 实现只能将内存归还给程序,而无法将内存归还给操作系统)。 物理内存和虚拟内存 要理解内存在程序是如何分配的,首先需要理解如何将内存从操作系统分配给程序。计算机上的每一个进程都认为自己可以访问所有的物理内存。显然,由于同时在运行多个程序,所以每个进程不可能拥有全部内存。实际上,这些进程使用的是 虚拟内存。 只是作为一个例子,让我们假定您的程序正在访问地址为 629 的内存。不过,虚拟内存系统不需要将其存储在位置为 629 的 RAM 。实际上,它甚至可以不在 RAM —— 如果物理 RAM 已经满了,它甚至可能已经被转移到硬盘上!由于这类地址不必反映内存所在的物理位置,所以它们被称为虚拟内存。操作系统维持着一个虚拟地址到物理地址的转换的表,以便计算机硬件可以正确地响应地址请求。并且,如果地址在硬盘上而不是在 RAM ,那么操作系统将暂时停止您的进程,将其他内存转存到硬盘,从硬盘上加载被请求的内存,然后再重新启动您的进程。这样,每个进程都获得了自己可以使用的地址空间,可以访问比您物理上安装的内存更多的内存。 在 32-位 x86 系统上,每一个进程可以访问 4 GB 内存。现在,大部分人的系统上并没有 4 GB 内存,即使您将 swap 也算上, 每个进程所使用的内存也肯定少于 4 GB。因此,当加载一个进程时,它会得到一个取决于某个称为 系统断点(system break)的特定地址的初始内存分配。该地址之后是未被映射的内存 —— 用于在 RAM 或者硬盘没有分配相应物理位置的内存。因此,如果一个进程运行超出了它初始分配的内存,那么它必须请求操作系统“映射进来(map in)”更多的内存。(映射是一个表示一一对应关系的数学术语 —— 当内存的虚拟地址有一个对应的物理地址来存储内存内容时,该内存将被映射。) 基于 UNIX 的系统有两个可映射到附加内存的基本系统调用: brk: brk() 是一个非常简单的系统调用。还记得系统断点吗?该位置是进程映射的内存边界。 brk() 只是简单地将这个位置向前或者向后移动,就可以向进程添加内存或者从进程取走内存。 mmap: mmap(),或者说是“内存映像”,类似于 brk(),但是更为灵活。首先,它可以映射任何位置的内存,而不单单只局限于进程。其次,它不仅可以将虚拟地址映射到物理的 RAM 或者 swap,它还可以将它们映射到文件和文件位置,这样,读写内存将对文件的数据进行读写。不过,在这里,我们只关心 mmap 向进程添加被映射的内存的能力。 munmap() 所做的事情与 mmap() 相反。 如您所见, brk() 或者 mmap() 都可以用来向我们的进程添加额外的虚拟内存。在我们的例子将使用 brk(),因为它更简单,更通用。 实现一个简单的分配程序 如果您曾经编写过很多 C 程序,那么您可能曾多次使用过 malloc() 和 free()。不过,您可能没有用一些时间去思考它们在您的操作系统是如何实现的。本节将向您展示 malloc 和 free 的一个最简化实现的代码,来帮助说明管理内存时都涉及到了哪些事情。 要试着运行这些示例,需要先 复制本代码清单,并将其粘贴到一个名为 malloc.c 的文件。接下来,我将一次一个部分地对该清单进行解释。 在大部分操作系统,内存分配由以下两个简单的函数来处理: void *malloc(long numbytes):该函数负责分配 numbytes 大小的内存,并返回指向第一个字节的指针。 void free(void *firstbyte):如果给定一个由先前的 malloc 返回的指针,那么该函数会将分配的空间归还给进程的“空闲空间”。 malloc_init 将是初始化内存分配程序的函数。它要完成以下三件事:将分配程序标识为已经初始化,找到系统最后一个有效内存地址,然后建立起指向我们管理的内存的指针。这三个变量都是全局变量: 清单 1. 我们的简单分配程序的全局变量 int has_initialized = 0; void *managed_memory_start; void *last_valid_address; 如前所述,被映射的内存的边界(最后一个有效地址)常被称为系统断点或者 当前断点。在很多 UNIX® 系统,为了指出当前系统断点,必须使用 sbrk(0) 函数。 sbrk 根据参数给出的字节数移动当前系统断点,然后返回新的系统断点。使用参数 0 只是返回当前断点。这里是我们的 malloc 初始化代码,它将找到当前断点并初始化我们的变量: 清单 2. 分配程序初始化函数 /* Include the sbrk function */ #include void malloc_init() { /* grab the last valid address from the OS */ last_valid_address = sbrk(0); /* we don't have any memory to manage yet, so *just set the beginning to be last_valid_address */ managed_memory_start = last_valid_address; /* Okay, we're initialized and ready to go */ has_initialized = 1; } 现在,为了完全地管理内存,我们需要能够追踪要分配和回收哪些内存。在对内存块进行了 free 调用之后,我们需要做的是诸如将它们标记为未被使用的等事情,并且,在调用 malloc 时,我们要能够定位未被使用的内存块。因此, malloc 返回的每块内存的起始处首先要有这个结构: 清单 3. 内存控制块结构定义 struct mem_control_block { int is_available; int size; }; 现在,您可能会认为当程序调用 malloc 时这会引发问题 —— 它们如何知道这个结构?答案是它们不必知道;在返回指针之前,我们会将其移动到这个结构之后,把它隐藏起来。这使得返回的指针指向没有用于任何其他用途的内存。那样,从调用程序的角度来看,它们所得到的全部是空闲的、开放的内存。然后,当通过 free() 将该指针传递回来时,我们只需要倒退几个内存字节就可以再次找到这个结构。 在讨论分配内存之前,我们将先讨论释放,因为它更简单。为了释放内存,我们必须要做的惟一一件事情就是,获得我们给出的指针,回退 sizeof(struct mem_control_block) 个字节,并将其标记为可用的。这里是对应的代码: 清单 4. 解除分配函数 void free(void *firstbyte) { struct mem_control_block *mcb; /* Backup from the given pointer to find the * mem_control_block */ mcb = firstbyte - sizeof(struct mem_control_block); /* Mark the block as being available */ mcb->is_available = 1; /* That's It! We're done. */ return; } 如您所见,在这个分配程序,内存的释放使用了一个非常简单的机制,在固定时间内完成内存释放。分配内存稍微困难一些。以下是该算法的略述: 清单 5. 主分配程序的伪代码 1. If our allocator has not been initialized, initialize it. 2. Add sizeof(struct mem_control_block) to the size requested. 3. start at managed_memory_start. 4. Are we at last_valid address? 5. If we are: A. We didn't find any existing space that was large enough -- ask the operating system for more and return that. 6. Otherwise: A. Is the current space available (check is_available from the mem_control_block)? B. If it is: i) Is it large enough (check "size" from the mem_control_block)? ii) If so: a. Mark it as unavailable b. Move past mem_control_block and return the pointer iii) Otherwise: a. Move forward "size" bytes b. Go back go step 4 C. Otherwise: i) Move forward "size" bytes ii) Go back to step 4 我们主要使用连接的指针遍历内存来寻找开放的内存块。这里是代码: 清单 6. 主分配程序 void *malloc(long numbytes) { /* Holds where we are looking in memory */ void *current_location; /* This is the same as current_location, but cast to a * memory_control_block */ struct mem_control_block *current_location_mcb; /* This is the memory location we will return. It will * be set to 0 until we find something suitable */ void *memory_location; /* Initialize if we haven't already done so */ if(! has_initialized) { malloc_init(); } /* The memory we search for has to include the memory * control block, but the users of malloc don't need * to know this, so we'll just add it in for them. */ numbytes = numbytes + sizeof(struct mem_control_block); /* Set memory_location to 0 until we find a suitable * location */ memory_location = 0; /* Begin searching at the start of managed memory */ current_location = managed_memory_start; /* Keep going until we have searched all allocated space */ while(current_location != last_valid_address) { /* current_location and current_location_mcb point * to the same address. However, current_location_mcb * is of the correct type, so we can use it as a struct. * current_location is a void pointer so we can use it * to calculate addresses. */ current_location_mcb = (struct mem_control_block *)current_location; if(current_location_mcb->is_available) { if(current_location_mcb->size >= numbytes) { /* Woohoo! We've found an open, * appropriately-size location. */ /* It is no longer available */ current_location_mcb->is_available = 0; /* We own it */ memory_location = current_location; /* Leave the loop */ break; } } /* If we made it here, it's because the Current memory * block not suitable; move to the next one */ current_location = current_location + current_location_mcb->size; } /* If we still don't have a valid location, we'll * have to ask the operating system for more memory */ if(! memory_location) { /* Move the program break numbytes further */ sbrk(numbytes); /* The new memory will be where the last valid * address left off */ memory_location = last_valid_address; /* We'll move the last valid address forward * numbytes */ last_valid_address = last_valid_address + numbytes; /* We need to initialize the mem_control_block */ current_location_mcb = memory_location; current_location_mcb->is_available = 0; current_location_mcb->size = numbytes; } /* Now, no matter what (well, except for error conditions), * memory_location has the address of the memory, including * the mem_control_block */ /* Move the pointer past the mem_control_block */ memory_location = memory_location + sizeof(struct mem_control_block); /* Return the pointer */ return memory_location; } 这就是我们的内存管理器。现在,我们只需要构建它,并在程序使用它即可。 运行下面的命令来构建 malloc 兼容的分配程序(实际上,我们忽略了 realloc() 等一些函数,不过, malloc() 和 free() 才是最主要的函数): 清单 7. 编译分配程序 gcc -shared -fpic malloc.c -o malloc.so 该程序将生成一个名为 malloc.so 的文件,它是一个包含有我们的代码的共享库。 在 UNIX 系统,现在您可以用您的分配程序来取代系统的 malloc(),做法如下: 清单 8. 替换您的标准的 malloc LD_PRELOAD=/path/to/malloc.so export LD_PRELOAD LD_PRELOAD 环境变量使动态链接器在加载任何可执行程序之前,先加载给定的共享库的符号。它还为特定库的符号赋予优先权。因此,从现在起,该会话的任何应用程序都将使用我们的 malloc(),而不是只有系统的应用程序能够使用。有一些应用程序不使用 malloc(),不过它们是例外。其他使用 realloc() 等其他内存管理函数的应用程序,或者错误地假定 malloc() 内部行为的那些应用程序,很可能会崩溃。ash shell 似乎可以使用我们的新 malloc() 很好地工作。 如果您想确保 malloc() 正在被使用,那么您应该通过向函数的入口点添加 write() 调用来进行测试。 我们的内存管理器在很多方面都还存在欠缺,但它可以有效地展示内存管理需要做什么事情。它的某些缺点包括: 由于它对系统断点(一个全局变量)进行操作,所以它不能与其他分配程序或者 mmap 一起使用。 当分配内存时,在最坏的情形下,它将不得不遍历 全部进程内存;其可能包括位于硬盘上的很多内存,这意味着操作系统将不得不花时间去向硬盘移入数据和从硬盘移出数据。 没有很好的内存不足处理方案( malloc 只假定内存分配是成功的)。 它没有实现很多其他的内存函数,比如 realloc()。 由于 sbrk() 可能会交回比我们请求的更多的内存,所以在堆(heap)的末端会遗漏一些内存。 虽然 is_available 标记只包含一位信息,但它要使用完整的 4-字节 的字。 分配程序不是线程安全的。 分配程序不能将空闲空间拼合为更大的内存块。 分配程序的过于简单的匹配算法会导致产生很多潜在的内存碎片。 我确信还有很多其他问题。这就是为什么它只是一个例子! 其他 malloc 实现 malloc() 的实现有很多,这些实现各有优点与缺点。在设计一个分配程序时,要面临许多需要折衷的选择,其包括: 分配的速度。 回收的速度。 有线程的环境的行为。 内存将要被用光时的行为。 局部缓存。 簿记(Bookkeeping)内存开销。 虚拟内存环境的行为。 小的或者大的对象。 实时保证。 每一个实现都有其自身的优缺点集合。在我们的简单的分配程序,分配非常慢,而回收非常快。另外,由于它在使用虚拟内存系统方面较差,所以它最适于处理大的对象。 还有其他许多分配程序可以使用。其包括: Doug Lea Malloc:Doug Lea Malloc 实际上是完整的一组分配程序,其包括 Doug Lea 的原始分配程序,GNU libc 分配程序和 ptmalloc。 Doug Lea 的分配程序有着与我们的版本非常类似的基本结构,但是它加入了索引,这使得搜索速度更快,并且可以将多个没有被使用的块组合为一个大的块。它还支持缓存,以便更快地再次使用最近释放的内存。 ptmalloc 是 Doug Lea Malloc 的一个扩展版本,支持多线程。在本文后面的 参考资料部分,有一篇描述 Doug Lea 的 Malloc 实现的文章。 BSD Malloc:BSD Malloc 是随 4.2 BSD 发行的实现,包含在 FreeBSD 之,这个分配程序可以从预先确实大小的对象构成的池分配对象。它有一些用于对象大小的 size 类,这些对象的大小为 2 的若干次幂减去某一常数。所以,如果您请求给定大小的一个对象,它就简单地分配一个与之匹配的 size 类。这样就提供了一个快速的实现,但是可能会浪费内存。在 参考资料部分,有一篇描述该实现的文章。 Hoard:编写 Hoard 的目标是使内存分配在多线程环境进行得非常快。因此,它的构造以锁的使用为心,从而使所有进程不必等待分配内存。它可以显著地加快那些进行很多分配和回收的多线程进程的速度。在 参考资料部分,有一篇描述该实现的文章。 众多可用的分配程序最有名的就是上述这些分配程序。如果您的程序有特别的分配需求,那么您可能更愿意编写一个定制的能匹配您的程序内存分配方式的分配程序。不过,如果不熟悉分配程序的设计,那么定制分配程序通常会带来比它们解决的问题更多的问题。要获得关于该主题的适当的介绍,请参阅 Donald Knuth 撰写的 The Art of Computer Programming Volume 1: Fundamental Algorithms 的第 2.5 节“Dynamic Storage Allocation”(请参阅 参考资料的链接)。它有点过时,因为它没有考虑虚拟内存环境,不过大部分算法都是基于前面给出的函数。 在 C++ ,通过重载 operator new(),您可以以每个类或者每个模板为单位实现自己的分配程序。在 Andrei Alexandrescu 撰写的 Modern C++ Design 的第 4 章(“Small Object Allocation”),描述了一个小对象分配程序(请参阅 参考资料的链接)。 基于 malloc() 的内存管理的缺点 不只是我们的内存管理器有缺点,基于 malloc() 的内存管理器仍然也有很多缺点,不管您使用的是哪个分配程序。对于那些需要保持长期存储的程序使用 malloc() 来管理内存可能会非常令人失望。如果您有大量的不固定的内存引用,经常难以知道它们何时被释放。生存期局限于当前函数的内存非常容易管理,但是对于生存期超出该范围的内存来说,管理内存则困难得多。而且,关于内存管理是由进行调用的程序还是由被调用的函数来负责这一问题,很多 API 都不是很明确。 因为管理内存的问题,很多程序倾向于使用它们自己的内存管理规则。C++ 的异常处理使得这项任务更成问题。有时好像致力于管理内存分配和清理的代码比实际完成计算任务的代码还要多!因此,我们将研究内存管理的其他选择。 回页首 半自动内存管理策略 引用计数 引用计数是一种 半自动(semi-automated)的内存管理技术,这表示它需要一些编程支持,但是它不需要您确切知道某一对象何时不再被使用。引用计数机制为您完成内存管理任务。 在引用计数,所有共享的数据结构都有一个域来包含当前活动“引用”结构的次数。当向一个程序传递一个指向某个数据结构指针时,该程序会将引用计数增加 1。实质上,您是在告诉数据结构,它正在被存储在多少个位置上。然后,当您的进程完成对它的使用后,该程序就会将引用计数减少 1。结束这个动作之后,它还会检查计数是否已经减到零。如果是,那么它将释放内存。 这样做的好处是,您不必追踪程序某个给定的数据结构可能会遵循的每一条路径。每次对其局部的引用,都将导致计数的适当增加或减少。这样可以防止在使用数据结构时释放该结构。不过,当您使用某个采用引用计数的数据结构时,您必须记得运行引用计数函数。另外,内置函数和第三方的库不会知道或者可以使用您的引用计数机制。引用计数也难以处理发生循环引用的数据结构。 要实现引用计数,您只需要两个函数 —— 一个增加引用计数,一个减少引用计数并当计数减少到零时释放内存。 一个示例引用计数函数集可能看起来如下所示: 清单 9. 基本的引用计数函数 /* Structure Definitions*/ /* Base structure that holds a refcount */ struct refcountedstruct { int refcount; } /* All refcounted structures must mirror struct * refcountedstruct for their first variables */ /* Refcount maintenance functions */ /* Increase reference count */ void REF(void *data) { struct refcountedstruct *rstruct; rstruct = (struct refcountedstruct *) data; rstruct->refcount++; } /* Decrease reference count */ void UNREF(void *data) { struct refcountedstruct *rstruct; rstruct = (struct refcountedstruct *) data; rstruct->refcount--; /* Free the structure if there are no more users */ if(rstruct->refcount == 0) { free(rstruct); } } REF 和 UNREF 可能会更复杂,这取决于您想要做的事情。例如,您可能想要为多线程程序增加锁,那么您可能想扩展 refcountedstruct,使它同样包含一个指向某个在释放内存之前要调用的函数的指针(类似于面向对象语言的析构函数 —— 如果您的结构包含这些指针,那么这是 必需的)。 当使用 REF 和 UNREF 时,您需要遵守这些指针的分配规则: UNREF 分配前左端指针(left-hand-side pointer)指向的值。 REF 分配后左端指针(left-hand-side pointer)指向的值。 在传递使用引用计数的结构的函数,函数需要遵循以下这些规则: 在函数的起始处 REF 每一个指针。 在函数的结束处 UNREF 第一个指针。 以下是一个使用引用计数的生动的代码示例: 清单 10. 使用引用计数的示例 /* EXAMPLES OF USAGE */ /* Data type to be refcounted */ struct mydata { int refcount; /* same as refcountedstruct */ int datafield1; /* Fields specific to this struct */ int datafield2; /* other declarations would go here as appropriate */ }; /* Use the functions in code */ void dosomething(struct mydata *data) { REF(data); /* Process data */ /* when we are through */ UNREF(data); } struct mydata *globalvar1; /* Note that in this one, we don't decrease the * refcount since we are maintaining the reference * past the end of the function call through the * global variable */ void storesomething(struct mydata *data) { REF(data); /* passed as a parameter */ globalvar1 = data; REF(data); /* ref because of Assignment */ UNREF(data); /* Function finished */ } 由于引用计数是如此简单,大部分程序员都自已去实现它,而不是使用库。不过,它们依赖于 malloc 和 free 等低层的分配程序来实际地分配和释放它们的内存。 在 Perl 等高级语言,进行内存管理时使用引用计数非常广泛。在这些语言,引用计数由语言自动地处理,所以您根本不必担心它,除非要编写扩展模块。由于所有内容都必须进行引用计数,所以这会对速度产生一些影响,但它极大地提高了编程的安全性和方便性。以下是引用计数的益处: 实现简单。 易于使用。 由于引用是数据结构的一部分,所以它有一个好的缓存位置。 不过,它也有其不足之处: 要求您永远不要忘记调用引用计数函数。 无法释放作为循环数据结构的一部分的结构。 减缓几乎每一个指针的分配。 尽管所使用的对象采用了引用计数,但是当使用异常处理(比如 try 或 setjmp()/ longjmp())时,您必须采取其他方法。 需要额外的内存来处理引用。 引用计数占用了结构的第一个位置,在大部分机器最快可以访问到的就是这个位置。 在多线程环境更慢也更难以使用。 C++ 可以通过使用 智能指针(smart pointers)来容忍程序员所犯的一些错误,智能指针可以为您处理引用计数等指针处理细节。不过,如果不得不使用任何先前的不能处理智能指针的代码(比如对 C 库的联接),实际上,使用它们的后果通实比不使用它们更为困难和复杂。因此,它通常只是有益于纯 C++ 项目。如果您想使用智能指针,那么您实在应该去阅读 Alexandrescu 撰写的 Modern C++ Design 一书的“Smart Pointers”那一章。 内存池 内存池是另一种半自动内存管理方法。内存池帮助某些程序进行自动内存管理,这些程序会经历一些特定的阶段,而且每个阶段都有分配给进程的特定阶段的内存。例如,很多网络服务器进程都会分配很多针对每个连接的内存 —— 内存的最大生存期限为当前连接的存在期。Apache 使用了池式内存(pooled memory),将其连接拆分为各个阶段,每个阶段都有自己的内存池。在结束每个阶段时,会一次释放所有内存。 在池式内存管理,每次内存分配都会指定内存池,从分配内存。每个内存池都有不同的生存期限。在 Apache ,有一个持续时间为服务器存在期的内存池,还有一个持续时间为连接的存在期的内存池,以及一个持续时间为请求的存在期的池,另外还有其他一些内存池。因此,如果我的一系列函数不会生成比连接持续时间更长的数据,那么我就可以完全从连接池分配内存,并知道在连接结束时,这些内存会被自动释放。另外,有一些实现允许注册 清除函数(cleanup functions),在清除内存池之前,恰好可以调用它,来完成在内存被清理前需要完成的其他所有任务(类似于面向对象的析构函数)。 要在自己的程序使用池,您既可以使用 GNU libc 的 obstack 实现,也可以使用 Apache 的 Apache Portable Runtime。GNU obstack 的好处在于,基于 GNU 的 Linux 发行版本默认会包括它们。Apache Portable Runtime 的好处在于它有很多其他工具,可以处理编写多平台服务器软件所有方面的事情。要深入了解 GNU obstack 和 Apache 的池式内存实现,请参阅 参考资料部分指向这些实现的文档的链接。 下面的假想代码列表展示了如何使用 obstack: 清单 11. obstack 的示例代码 #include #include /* Example code listing for using obstacks */ /* Used for obstack macros (xmalloc is a malloc function that exits if memory is exhausted */ #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free /* Pools */ /* Only permanent allocations should go in this pool */ struct obstack *global_pool; /* This pool is for per-connection data */ struct obstack *connection_pool; /* This pool is for per-request data */ struct obstack *request_pool; void allocation_failed() { exit(1); } int main() { /* Initialize Pools */ global_pool = (struct obstack *) xmalloc (sizeof (struct obstack)); obstack_init(global_pool); connection_pool = (struct obstack *) xmalloc (sizeof (struct obstack)); obstack_init(connection_pool); request_pool = (struct obstack *) xmalloc (sizeof (struct obstack)); obstack_init(request_pool); /* Set the error handling function */ obstack_alloc_failed_handler = &allocation_failed; /* Server main loop */ while(1) { wait_for_connection(); /* We are in a connection */ while(more_requests_available()) { /* Handle request */ handle_request(); /* Free all of the memory allocated * in the request pool */ obstack_free(request_pool, NULL); } /* We're finished with the connection, time * to free that pool */ obstack_free(connection_pool, NULL); } } int handle_request() { /* Be sure that all object allocations are allocated * from the request pool */ int bytes_i_need = 400; void *data1 = obstack_alloc(request_pool, bytes_i_need); /* Do stuff to process the request */ /* return */ return 0; } 基本上,在操作的每一个主要阶段结束之后,这个阶段的 obstack 会被释放。不过,要注意的是,如果一个过程需要分配持续时间比当前阶段更长的内存,那么它也可以使用更长期限的 obstack,比如连接或者全局内存。传递给 obstack_free() 的 NULL 指出它应该释放 obstack 的全部内容。可以用其他的值,但是它们通常不怎么实用。 使用池式内存分配的益处如下所示: 应用程序可以简单地管理内存。 内存分配和回收更快,因为每次都是在一个池完成的。分配可以在 O(1) 时间内完成,释放内存池所需时间也差不多(实际上是 O(n) 时间,不过在大部分情况下会除以一个大的因数,使其变成 O(1))。 可以预先分配错误处理池(Error-handling pools),以便程序在常规内存被耗尽时仍可以恢复。 有非常易于使用的标准实现。 池式内存的缺点是: 内存池只适用于操作可以分阶段的程序。 内存池通常不能与第三方库很好地合作。 如果程序的结构发生变化,则不得不修改内存池,这可能会导致内存管理系统的重新设计。 您必须记住需要从哪个池进行分配。另外,如果在这里出错,就很难捕获该内存池。 回页首 垃圾收集 垃圾收集(Garbage collection)是全自动地检测并移除不再使用的数据对象。垃圾收集器通常会在当可用内存减少到少于一个具体的阈值时运行。通常,它们以程序所知的可用的一组“基本”数据 —— 栈数据、全局变量、寄存器 —— 作为出发点。然后它们尝试去追踪通过这些数据连接到每一块数据。收集器找到的都是有用的数据;它没有找到的就是垃圾,可以被销毁并重新使用这些无用的数据。为了有效地管理内存,很多类型的垃圾收集器都需要知道数据结构内部指针的规划,所以,为了正确运行垃圾收集器,它们必须是语言本身的一部分。 收集器的类型 复制(copying): 这些收集器将内存存储器分为两部分,只允许数据驻留在其一部分上。它们定时地从“基本”的元素开始将数据从一部分复制到另一部分。内存新近被占用的部分现在成为活动的,另一部分上的所有内容都认为是垃圾。另外,当进行这项复制操作时,所有指针都必须被更新为指向每个内存条目的新位置。因此,为使用这种垃圾收集方法,垃圾收集器必须与编程语言集成在一起。 标记并清理(Mark and sweep):每一块数据都被加上一个标签。不定期的,所有标签都被设置为 0,收集器从“基本”的元素开始遍历数据。当它遇到内存时,就将标签标记为 1。最后没有被标记为 1 的所有内容都认为是垃圾,以后分配内存时会重新使用它们。 增量的(Incremental):增量垃圾收集器不需要遍历全部数据对象。因为在收集期间的突然等待,也因为与访问所有当前数据相关的缓存问题(所有内容都不得不被页入(page-in)),遍历所有内存会引发问题。增量收集器避免了这些问题。 保守的(Conservative):保守的垃圾收集器在管理内存时不需要知道与数据结构相关的任何信息。它们只查看所有数据类型,并假定它们 可以全部都是指针。所以,如果一个字节序列可以是一个指向一块被分配的内存的指针,那么收集器就将其标记为正在被引用。有时没有被引用的内存会被收集,这样会引发问题,例如,如果一个整数域包含一个值,该值是已分配内存的地址。不过,这种情况极少发生,而且它只会浪费少量内存。保守的收集器的优势是,它们可以与任何编程语言相集成。 Hans Boehm 的保守垃圾收集器是可用的最流行的垃圾收集器之一,因为它是免费的,而且既是保守的又是增量的,可以使用 --enable-redirect-malloc 选项来构建它,并且可以将它用作系统分配程序的简易替代者(drop-in replacement)(用 malloc/ free 代替它自己的 API)。实际上,如果这样做,您就可以使用与我们在示例分配程序所使用的相同的 LD_PRELOAD 技巧,在系统上的几乎任何程序启用垃圾收集。如果您怀疑某个程序正在泄漏内存,那么您可以使用这个垃圾收集器来控制进程。在早期,当 Mozilla 严重地泄漏内存时,很多人在其使用了这项技术。这种垃圾收集器既可以在 Windows® 下运行,也可以在 UNIX 下运行。 垃圾收集的一些优点: 您永远不必担心内存的双重释放或者对象的生命周期。 使用某些收集器,您可以使用与常规分配相同的 API。 其缺点包括: 使用大部分收集器时,您都无法干涉何时释放内存。 在多数情况下,垃圾收集比其他形式的内存管理更慢。 垃圾收集错误引发的缺陷难于调试。 如果您忘记将不再使用的指针设置为 null,那么仍然会有内存泄漏。 回页首 结束语 一切都需要折衷:性能、易用、易于实现、支持线程的能力等,这里只列出了其的一些。为了满足项目的要求,有很多内存管理模式可以供您使用。每种模式都有大量的实现,各有其优缺点。对很多项目来说,使用编程环境默认的技术就足够了,不过,当您的项目有特殊的需要时,了解可用的选择将会有帮助。下表对比了本文涉及的内存管理策略。 表 1. 内存分配策略的对比 策略 分配速度 回收速度 局部缓存 易用性 通用性 实时可用 SMP 线程友好 定制分配程序 取决于实现 取决于实现 取决于实现 很难 无 取决于实现 取决于实现 简单分配程序 内存使用少时较快 很快 差 容易 高 否 否 GNU malloc 容易 高 否 Hoard 容易 高 否 是 引用计数 N/A N/A 非常好 是(取决于 malloc 实现) 取决于实现 池 非常快 极好 是(取决于 malloc 实现) 取决于实现 垃圾收集 (进行收集时慢) 否 几乎不 增量垃圾收集 否 几乎不 增量保守垃圾收集 容易 高 否 几乎不 参考资料 您可以参阅本文在 developerWorks 全球站点上的 英文原文。 Web 上的文档 GNU C Library 手册的 obstacks 部分 提供了 obstacks 编程接口。 Apache Portable Runtime 文档 描述了它们的池式分配程序的接口。 基本的分配程序 Doug Lea 的 Malloc 是最流行的内存分配程序之一。 BSD Malloc 用于大部分基于 BSD 的系统。 ptmalloc 起源于 Doug Lea 的 malloc,用于 GLIBC 之。 Hoard 是一个为多线程应用程序优化的 malloc 实现。 GNU Memory-Mapped Malloc(GDB 的组成部分) 是一个基于 mmap() 的 malloc 实现。 池式分配程序 GNU Obstacks(GNU Libc 的组成部分)是安装最多的池式分配程序,因为在每一个基于 glibc 的系统都有它。 Apache 的池式分配程序(Apache Portable Runtime ) 是应用最为广泛的池式分配程序。 Squid 有其自己的池式分配程序。 NetBSD 也有其自己的池式分配程序。 talloc 是一个池式分配程序,是 Samba 的组成部分。 智能指针和定制分配程序 Loki C++ Library 有很多为 C++ 实现的通用模式,包括智能指针和一个定制的小对象分配程序。 垃圾收集器 Hahns Boehm Conservative Garbage Collector 是最流行的开源垃圾收集器,它可以用于常规的 C/C++ 程序。 关于现代操作系统的虚拟内存的文章 Marshall Kirk McKusick 和 Michael J. Karels 合著的 A New Virtual Memory Implementation for Berkeley UNIX 讨论了 BSD 的 VM 系统。 Mel Gorman's Linux VM Documentation 讨论了 Linux VM 系统。 关于 malloc 的文章 Poul-Henning Kamp 撰写的 Malloc in Modern Virtual Memory Environments 讨论的是 malloc 以及它如何与 BSD 虚拟内存交互。 Berger、McKinley、Blumofe 和 Wilson 合著的 Hoard -- a Scalable Memory Allocator for Multithreaded Environments 讨论了 Hoard 分配程序的实现。 Marshall Kirk McKusick 和 Michael J. Karels 合著的 Design of a General Purpose Memory Allocator for the 4.3BSD UNIX Kernel 讨论了内核级的分配程序。 Doug Lea 撰写的 A Memory Allocator 给出了一个关于设计和实现分配程序的概述,其包括设计选择与折衷。 Emery D. Berger 撰写的 Memory Management for High-Performance Applications 讨论的是定制内存管理以及它如何影响高性能应用程序。 关于定制分配程序的文章 Doug Lea 撰写的 Some Storage Management Techniques for Container Classes 描述的是为 C++ 类编写定制分配程序。 Berger、Zorn 和 McKinley 合著的 Composing High-Performance Memory Allocators 讨论了如何编写定制分配程序来加快具体工作的速度。 Berger、Zorn 和 McKinley 合著的 Reconsidering Custom Memory Allocation 再次提及了定制分配的主题,看是否真正值得为其费心。 关于垃圾收集的文章 Paul R. Wilson 撰写的 Uniprocessor Garbage Collection Techniques 给出了垃圾收集的一个基本概述。 Benjamin Zorn 撰写的 The Measured Cost of Garbage Collection 给出了关于垃圾收集和性能的硬数据(hard data)。 Hans-Juergen Boehm 撰写的 Memory Allocation Myths and Half-Truths 给出了关于垃圾收集的神话(myths)。 Hans-Juergen Boehm 撰写的 Space Efficient Conservative Garbage Collection 是一篇描述他的用于 C/C++ 的垃圾收集器的文章。 Web 上的通用参考资料 内存管理参考 有很多关于内存管理参考资料和技术文章的链接。 关于内存管理和内存层级的 OOPS Group Papers 是非常好的一组关于此主题的技术文章。 C++ 的内存管理讨论的是为 C++ 编写定制的分配程序。 Programming Alternatives: Memory Management 讨论了程序员进行内存管理时的一些选择。 垃圾收集 FAQ 讨论了关于垃圾收集您需要了解的所有内容。 Richard Jones 的 Garbage Collection Bibliography 有指向任何您想要的关于垃圾收集的文章的链接。 书籍 Michael Daconta 撰写的 C++ Pointers and Dynamic Memory Management 介绍了关于内存管理的很多技术。 Frantisek Franek 撰写的 Memory as a Programming Concept in C and C++ 讨论了有效使用内存的技术与工具,并给出了在计算机编程应当引起注意的内存相关错误的角色。 Richard Jones 和 Rafael Lins 合著的 Garbage Collection: Algorithms for Automatic Dynamic Memory Management 描述了当前使用的最常见的垃圾收集算法。 在 Donald Knuth 撰写的 The Art of Computer Programming 第 1 卷 Fundamental Algorithms 的第 2.5 节“Dynamic Storage Allocation”,描述了实现基本的分配程序的一些技术。 在 Donald Knuth 撰写的 The Art of Computer Programming 第 1 卷 Fundamental Algorithms 的第 2.3.5 节“Lists and Garbage Collection”,讨论了用于列表的垃圾收集算法。 Andrei Alexandrescu 撰写的 Modern C++ Design 第 4 章“Small Object Allocation”描述了一个比 C++ 标准分配程序效率高得多的一个高速小对象分配程序。 Andrei Alexandrescu 撰写的 Modern C++ Design 第 7 章“Smart Pointers”描述了在 C++ 智能指针的实现。 Jonathan 撰写的 Programming from the Ground Up 第 8 章“Intermediate Memory Topics”有本文使用的简单分配程序的一个汇编语言版本。 来自 developerWorks 自我管理数据缓冲区内存 (developerWorks,2004 年 1 月)略述了一个用于管理内存的自管理的抽象数据缓存器的伪 C (pseudo-C)实现。 A framework for the user defined malloc replacement feature (developerWorks,2002 年 2 月)展示了如何利用 AIX 的一个工具,使用自己设计的内存子系统取代原有的内存子系统。 掌握 Linux 调试技术 (developerWorks,2002 年 8 月)描述了可以使用调试方法的 4 种不同情形:段错误、内存溢出、内存泄漏和挂起。 在 处理 Java 程序的内存漏洞 (developerWorks,2001 年 2 月),了解导致 Java 内存泄漏的原因,以及何时需要考虑它们。 在 developerWorks Linux 专区,可以找到更多为 Linux 开发人员准备的参考资料。 从 developerWorks 的 Speed-start your Linux app 专区,可以下载运行于 Linux 之上的 IBM 间件产品的免费测试版本,其包括 WebSphere® Studio Application Developer、WebSphere Application Server、DB2® Universal Database、Tivoli® Access Manager 和 Tivoli Directory Server,查找 how-to 文章和技术支持。 通过参与 developerWorks blogs 加入到 developerWorks 社区。 可以在 Developer Bookstore Linux 专栏定购 打折出售的 Linux 书籍。 关于作者 Jonathan Bartlett 是 Programming from the Ground Up 一书的作者,这本书介绍的是 Linux 汇编语言编程。Jonathan Bartlett 是 New Media Worx 的总开发师,负责为客户开发 Web、视频、kiosk 和桌面应用程序。您可以通过 [email protected] 与 Jonathan 联系。
文件为doc版,可自行转成txt,在手机上看挺好的。 本资源来自网络,如有纰漏还请告知,如觉得还不错,请留言告知后来人,谢谢!!!!! 入门学习Linux常用必会60个命令实例详解 Linux必学的60个命令 Linux提供了大量的命令,利用它可以有效地完成大量的工作,如磁盘操作、文件存取、目录操作、进程管理、文件权限设定等。所以,在Linux系统上工作离不开使用系统提供的命令。要想真正理解Linux系统,就必须从Linux命令学起,通过基础的命令学习可以进一步理解Linux系统。 不同Linux发行版的命令数量不一样,但Linux发行版本最少的命令也有200多个。这里笔者把比较重要和使用频率最多的命令,按照它们在系统的作用分成下面六个部分一一介绍。 ◆ 安装和登录命令:login、shutdown、halt、reboot、install、mount、umount、chsh、exit、last; ◆ 文件处理命令:file、mkdir、grep、dd、find、mv、ls、diff、cat、ln; ◆ 系统管理相关命令:df、top、free、quota、at、lp、adduser、groupadd、kill、crontab; ◆ 网络操作命令:ifconfig、ip、ping、netstat、telnet、ftp、route、rlogin、rcp、finger、mail、 nslookup; ◆ 系统安全相关命令:passwd、su、umask、chgrp、chmod、chown、chattr、sudo ps、who; ◆ 其它命令:tar、unzip、gunzip、unarj、mtools、man、unendcode、uudecode。 本文以Mandrake Linux 9.1(Kenrel 2.4.21)为例,介绍Linux下的安装和登录命令。 immortality按:请用ctrl+f在本页查找某一部分的内容或某一命令的用法。 -------------------------------------------------------------------------------- Linux必学的60个命令(1)-安装与登陆命令 login 1.作用 login的作用是登录系统,它的使用权限是所有用户。 2.格式 login [name][-p ][-h 主机名称] 3.主要参数 -p:通知login保持现在的环境参数。 -h:用来向远程登录的之间传输用户名。 如果选择用命令行模式登录Linux的话,那么看到的第一个Linux命令就是login:。 一般界面是这样的: Manddrake Linux release 9.1(Bamboo) for i586 renrel 2.4.21-0.13mdk on i686 / tty1 localhost login:root password: 上面代码,第一行是Linux发行版本号,第二行是内核版本号和登录的虚拟控制台,我们在第三行输入登录名,按“Enter”键在Password后输入账户密码,即可登录系统。出于安全考虑,输入账户密码时字符不会在屏幕上回显,光标也不移动。 登录后会看到下面这个界面(以超级用户为例): [root@localhost root]# last login:Tue ,Nov 18 10:00:55 on vc/1 上面显示的是登录星期、月、日、时间和使用的虚拟控制台。 4.应用技巧 Linux 是一个真正的多用户操作系统,可以同时接受多个用户登录,还允许一个用户进行多次登录。这是因为Linux和许多版本的Unix一样,提供了虚拟控制台的访问方式,允许用户在同一时间从控制台(系统的控制台是与系统直接相连的监视器和键盘)进行多次登录。每个虚拟控制台可以看作是一个独立的工作站,工作台之间可以切换。虚拟控制台的切换可以通过按下Alt键和一个功能键来实现,通常使用F1-F6 。 例如,用户登录后,按一下“Alt+ F2”键,用户就可以看到上面出现的“login:”提示符,说明用户看到了第二个虚拟控制台。然后只需按“Alt+ F1”键,就可以回到第一个虚拟控制台。一个新安装的Linux系统允许用户使用“Alt+F1”到“Alt+F6”键来访问前六个虚拟控制台。虚拟控制台最有用的是,当一个程序出错造成系统死锁时,可以切换到其它虚拟控制台工作,关闭这个程序。 shutdown 1.作用 shutdown命令的作用是关闭计算机,它的使用权限是超级用户。 2.格式 shutdown [-h][-i][-k][-m][-t] 3.重要参数 -t:在改变到其它运行级别之前,告诉init程序多久以后关机。 -k:并不真正关机,只是送警告信号给每位登录者。 -h:关机后关闭电源。 -c:cancel current process取消目前正在执行的关机程序。所以这个选项当然没有时间参数,但是可以输入一个用来解释的讯息,而这信息将会送到每位使用者。 -F:在重启计算机时强迫fsck。 -time:设定关机前的时间。 -m: 将系统改为单用户模式。 -i:关机时显示系统信息。 4.命令说明 shutdown 命令可以安全地将系统关机。有些用户会使用直接断掉电源的方式来关闭Linux系统,这是十分危险的。因为Linux与Windows不同,其后台运行着许多进程,所以强制关机可能会导致进程的数据丢失,使系统处于不稳定的状态,甚至在有的系统会损坏硬件设备(硬盘)。在系统关机前使用 shutdown命令,系统管理员会通知所有登录的用户系统将要关闭,并且login指令会被冻结,即新的用户不能再登录。 halt 1.作用 halt命令的作用是关闭系统,它的使用权限是超级用户。 2.格式 halt [-n] [-w] [-d] [-f] [-i] [-p] 3.主要参数说明 -n:防止sync系统调用,它用在用fsck修补根分区之后,以阻止内核用老版本的超级块覆盖修补过的超级块。 -w:并不是真正的重启或关机,只是写wtmp(/var/log/wtmp)纪录。 -f:没有调用shutdown,而强制关机或重启。 -i:关机(或重启)前,关掉所有的网络接口。 -f:强迫关机,不呼叫shutdown这个指令。 -p: 当关机的时候顺便做关闭电源的动作。 -d:关闭系统,但不留下纪录。  4.命令说明 halt 就是调用shutdown -h。halt执行时,杀死应用进程,执行sync(将存于buffer的资料强制写入硬盘)系统调用,文件系统写操作完成后就会停止内核。若系统的运行级别为0或6,则关闭系统;否则以shutdown指令(加上-h参数)来取代。  reboot 1.作用 reboot命令的作用是重新启动计算机,它的使用权限是系统管理者。 2.格式 reboot [-n] [-w] [-d] [-f] [-i] 3.主要参数 -n: 在重开机前不做将记忆体资料写回硬盘的动作。 -w: 并不会真的重开机,只是把记录写到/var/log/wtmp文件里。 -d: 不把记录写到/var/log/wtmp文件里(-n这个参数包含了-d)。 -i: 在重开机之前先把所有与网络相关的装置停止。 install 1.作用 install命令的作用是安装或升级软件或备份数据,它的使用权限是所有用户。 2.格式 (1)install [选项]... 来源 目的地 (2)install [选项]... 来源... 目录 (3)install -d [选项]... 目录... 在前两种格式,会将复制至或将多个文件复制至已存在的,同时设定权限模式及所有者/所属组。在第三种格式,会创建所有指定的目录及它们的主目录。长选项必须用的参数在使用短选项时也是必须的。 3.主要参数 --backup[=CONTROL]:为每个已存在的目的地文件进行备份。 -b:类似 --backup,但不接受任何参数。 -c:(此选项不作处理)。 -d,--directory:所有参数都作为目录处理,而且会创建指定目录的所有主目录。 -D:创建前的所有主目录,然后将复制至 ;在第一种使用格式有用。 -g,--group=组:自行设定所属组,而不是进程目前的所属组。 -m,--mode=模式:自行设定权限模式 (像chmod),而不是rwxr-xr-x。 -o,--owner=所有者:自行设定所有者 (只适用于超级用户)。 -p,--preserve-timestamps:以文件的访问/修改时间作为相应的目的地文件的时间属性。 -s,--strip:用strip命令删除symbol table,只适用于第一及第二种使用格式。 -S,--suffix=后缀:自行指定备份文件的。 -v,--verbose:处理每个文件/目录时印出名称。 --help:显示此帮助信息并离开。 --version:显示版本信息并离开。 mount 1.作用 mount命令的作用是加载文件系统,它的用权限是超级用户或/etc/fstab允许的使用者。 2.格式 mount -a [-fv] [-t vfstype] [-n] [-rw] [-F] device dir 3.主要参数 -h:显示辅助信息。 -v:显示信息,通常和-f用来除错。 -a:将/etc/fstab定义的所有文件系统挂上。 -F:这个命令通常和-a一起使用,它会为每一个mount的动作产生一个行程负责执行。在系统需要挂上大量NFS文件系统时可以加快加载的速度。 -f:通常用于除错。它会使mount不执行实际挂上的动作,而是模拟整个挂上的过程,通常会和-v一起使用。 -t vfstype:显示被加载文件系统类型。 -n:一般而言,mount挂上后会在/etc/mtab写入一笔资料,在系统没有可写入文件系统的情况下,可以用这个选项取消这个动作。 4.应用技巧 在Linux 和Unix系统上,所有文件都是作为一个大型树(以/为根)的一部分访问的。要访问CD-ROM上的文件,需要将CD-ROM设备挂装在文件树的某个挂装点。如果发行版安装了自动挂装包,那么这个步骤可自动进行。在Linux,如果要使用硬盘、光驱等储存设备,就得先将它加载,当储存设备挂上了之后,就可以把它当成一个目录来访问。挂上一个设备使用mount命令。在使用mount这个指令时,至少要先知道下列三种信息:要加载对象的文件系统类型、要加载对象的设备名称及要将设备加载到哪个目录下。 (1)Linux可以识别的文件系统 ◆ Windows 95/98常用的FAT 32文件系统:vfat ; ◆ Win NT/2000 的文件系统:ntfs ; ◆ OS/2用的文件系统:hpfs; ◆ Linux用的文件系统:ext2、ext3; ◆ CD-ROM光盘用的文件系统:iso9660。 虽然vfat是指FAT 32系统,但事实上它也兼容FAT 16的文件系统类型。 (2)确定设备的名称 在Linux ,设备名称通常都存在/dev里。这些设备名称的命名都是有规则的,可以用“推理”的方式把设备名称找出来。例如,/dev/hda1这个 IDE设备,hd是Hard Disk(硬盘)的,sd是SCSI Device,fd是Floppy Device(或是Floppy Disk?)。a代表第一个设备,通常IDE接口可以接上4个IDE设备(比如4块硬盘)。所以要识别IDE硬盘的方法分别就是hda、hdb、hdc、 hdd。hda1的“1”代表hda的第一个硬盘分区 (partition),hda2代表hda的第二主分区,第一个逻辑分区从hda5开始,依此类推。此外,可以直接检查 /var/log/messages文件,在该文件可以找到计算机开机后系统已辨认出来的设备代号。 (3)查找挂接点 在决定将设备挂接之前,先要查看一下计算机是不是有个/mnt的空目录,该目录就是专门用来当作挂载点(Mount Point)的目录。建议在/mnt里建几个/mnt/cdrom、/mnt/floppy、/mnt/mo等目录,当作目录的专用挂载点。举例而言,如要挂载下列5个设备,其执行指令可能如下 (假设都是Linux的ext2系统,如果是Windows XX请将ext2改成vfat): 软盘 ===>mount -t ext2 /dev/fd0 /mnt/floppy cdrom ===>mount -t iso9660 /dev/hdc /mnt/cdrom SCSI cdrom ===>mount -t iso9660 /dev/sdb /mnt/scdrom SCSI cdr ===>mount -t iso9660 /dev/sdc /mnt/scdr 不过目前大多数较新的Linux发行版本(包括红旗 LinuxLinux、Mandrake Linux等)都可以自动挂装文件系统,但Red Hat Linux除外。 umount 1.作用 umount命令的作用是卸载一个文件系统,它的使用权限是超级用户或/etc/fstab允许的使用者。 2.格式 unmount -a [-fFnrsvw] [-t vfstype] [-n] [-rw] [-F] device dir 3.使用说明 umount 命令是mount命令的逆操作,它的参数和使用方法和mount命令是一样的。Linux挂装CD-ROM后,会锁定CD—ROM,这样就不能用CD- ROM面板上的Eject按钮弹出它。但是,当不再需要光盘时,如果已将/cdrom作为符号链接,请使用umount/cdrom来卸装它。仅当无用户正在使用光盘时,该命令才会成功。该命令包括了将带有当前工作目录当作该光盘的目录的终端窗口。 chsh 1.作用 chsh命令的作用是更改使用者shell设定,它的使用权限是所有使用者。 2.格式 chsh [ -s ] [ -list] [ --help ] [ -v ] [ username ] 3.主要参数 -l:显示系统所有Shell类型。 -v:显示Shell版本号。 4.应用技巧 前面介绍了Linux下有多种Shell,一般缺省的是Bash,如果想更换Shell类型可以使用chsh命令。先输入账户密码,然后输入新Shell类型,如果操作正确系统会显示“Shell change”。其界面一般如下: Changing fihanging shell for cao Password: New shell [/bin/bash]: /bin/tcsh 上面代码,[ ]内是目前使用的Shell。普通用户只能修改自己的Shell,超级用户可以修改全体用户的Shell。要想查询系统提供哪些Shell,可以使用chsh -l 命令,见图1所示。 图1 系统可以使用的Shell类型 从图1可以看到,笔者系统可以使用的Shell有bash(缺省)、csh、sh、tcsh四种。 exit 1.作用 exit命令的作用是退出系统,它的使用权限是所有用户。 2.格式 exit 3.参数 exit命令没有参数,运行后退出系统进入登录界面。 last 1.作用 last命令的作用是显示近期用户或终端的登录情况,它的使用权限是所有用户。通过last命令查看该程序的log,管理员可以获知谁曾经或企图连接系统。 2.格式 1ast[—n][-f file][-t tty] [—h 节点][-I —IP][—1][-y][1D] 3.主要参数 -n:指定输出记录的条数。 -f file:指定用文件file作为查询用的log文件。 -t tty:只显示指定的虚拟控制台上登录情况。 -h 节点:只显示指定的节点上的登录情况。 -i IP:只显示指定的IP上登录的情况。 -1:用IP来显示远端地址。 -y:显示记录的年、月、日。 -ID:知道查询的用户名。 -x:显示系统关闭、用户登录和退出的历史。 动手练习 上面介绍了Linux安装和登录命令,下面介绍几个实例,动手练习一下刚才讲过的命令。 1.一次运行多个命令 在一个命令行可以执行多个命令,用分号将各个命令隔开即可,例如: #last -x;halt 上面代码表示在显示系统关闭、用户登录和退出的历史后关闭计算机。 2.利用mount挂装文件系统访问Windows系统 许多Linux发行版本现在都可以自动加载Vfat分区来访问Windows系统,而Red Hat各个版本都没有自动加载Vfat分区,因此还需要进行手工操作。 mount 可以将Windows分区作为Linux的一个“文件”挂接到Linux的一个空文件夹下,从而将Windows的分区和/mnt这个目录联系起来。因此,只要访问这个文件夹就相当于访问该分区了。首先要在/mnt下建立winc文件夹,在命令提示符下输入下面命令: #mount -t vfat /dev/hda1 /mnt/winc 即表示将Windows的C分区挂到Liunx的/mnt/winc目录下。这时,在/mnt/winc目录下就可以看到WindowsC盘的内容了。使用类似的方法可以访问Windows系统的D、E盘。在Linux系统显示Windows的分区一般顺序这样的:hda1为C盘、hda5为D盘、 hda6为E盘……以此类推。上述方法可以查看Windows系统有一个很大的问题,就是Windows的所有文文件名或文件夹名全部显示为问号 “?”,而英文却可以正常显示。我们可以通过加入一些参数让它显示文。还以上面的操作为例,此时输入命令: #mount -t vfat -o iocharset=cp936 /dev/hda1 /mnt/winc 现在它就可以正常显示文了。 3.使用mount加挂闪盘上的文件系统Linux下使用闪盘非常简单。Linux对USB设备有很好的支持,当插入闪盘后,闪盘被识别为一个SCSI盘,通常输入以下命令: # mount /dev/sda1 /usb 就能够加挂闪盘上的文件系统。 小知识 Linux命令与Shell 所谓Shell,就是命令解释程序,它提供了程序设计接口,可以使用程序来编程。学习Shell对于Linux初学者理解Linux系统是非常重要的。 Linux系统的Shell作为操作系统的外壳,为用户提供了使用操作系统的接口。Shell是命令语言、命令解释程序及程序设计语言的统称,是用户和 Linux内核之间的接口程序。如果把Linux内核想象成一个球体的心,Shell就是围绕内核的外层。当从Shell或其它程序向Linux传递命令时,内核会做出相应的反应。Shell在Linux系统的作用和MS DOS下的COMMAND.COM和Windows 95/98 的 explorer.exe相似。Shell虽然不是系统核心的一部分,只是系统核心的一个外延,但它能够调用系统内核的大部分功能。因此,可以说 Shell是Unux/Linux最重要的实用程序。 Linux的Shell有多种类型,其最常用的是Bourne Shell(sh)、C Shell(csh)和Korn Shell(ksh)。大多数Linux发行版本缺省的Shell是Bourne Again Shell,它是Bourne Shell的扩展,简称bash,与Bourne Shell完全向后兼容,并且在Bourne Shell的基础上增加了很多特性。bash放在/bin/bash,可以提供如命令补全、命令编辑和命令历史表等功能。它还包含了很多C Shell和Korn Shell的优点,有灵活和强大的编程接口,同时又有很友好的用户界面。Linux系统200多个命令有40个是bash的内部命令,主要包括 exit、less、lp、kill、 cd、pwd、fc、fg等。 -------------------------------------------------------------------------------- Linux必学的60个命令(2)-文件处理命令 Linux 系统信息存放在文件里,文件与普通的公务文件类似。每个文件都有自己的名字、内容、存放地址及其它一些管理信息,如文件的用户、文件的大小等。文件可以是一封信、一个通讯录,或者是程序的源语句、程序的数据,甚至可以包括可执行的程序和其它非正文内容。 Linux文件系统具有良好的结构,系统提供了很多文件处理程序。这里主要介绍常用的文件处理命令。 file 1.作用 件内容判断文件类型,使用权限是所有用户。 2.格式 file通过探测文 file [options] 文件名 3.[options]主要参数 -v:在标准输出后显示版本信息,并且退出。 -z:探测压缩过的文件类型。 -L:允许符合连接。 -f name:从文件namefile读取要分析的文件名列表。 4.简单说明 使用file命令可以知道某个文件究竟是二进制(ELF格式)的可执行文件, 还是Shell Script文件,或者是其它的什么格式。file能识别的文件类型有目录、Shell脚本、英文文本、二进制可执行文件、C语言源文件、文本文件、DOS的可执行文件。 5.应用实例 如果我们看到一个没有后缀的文件grap,可以使用下面命令: $ file grap grap: English text 此时系统显示这是一个英文文本文件。需要说明的是,file命令不能探测包括图形、音频、视频等多媒体文件类型。 mkdir 1.作用 mkdir命令的作用是建立名称为dirname的子目录,与MS DOS下的md命令类似,它的使用权限是所有用户。 2.格式 mkdir [options] 目录名 3.[options]主要参数 -m, --mode=模式:设定权限,与chmod类似。 -p, --parents:需要时创建上层目录;如果目录早已存在,则不当作错误。 -v, --verbose:每次创建新目录都显示信息。 --version:显示版本信息后离开。 4.应用实例 在进行目录创建时可以设置目录的权限,此时使用的参数是“-m”。假设要创建的目录名是“tsk”,让所有用户都有rwx(即读、写、执行的权限),那么可以使用以下命令: $ mkdir -m 777 tsk grep 1.作用 grep命令可以指定文件搜索特定的内容,并将含有这些内容的行标准输出。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。 2.格式 grep [options] 3.主要参数 [options]主要参数: -c:只输出匹配行的计数。 -I:不区分大小写(只适用于单字符)。 -h:查询多文件时不显示文件名。 -l:查询多文件时只输出包含匹配字符的文件名。 -n:显示匹配行及行号。 -s:不显示不存在或无匹配文本的错误信息。 -v:显示不包含匹配文本的所有行。 pattern正则表达式主要参数: \:忽略正则表达式特殊字符的原有含义。 ^:匹配正则表达式的开始行。 $: 匹配正则表达式的结束行。 \:到匹配正则表达式的行结束。 [ ]:单个字符,如[A]即A符合要求 。 [ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。 。:所有的单个字符。 * :有字符,长度可以为0。 正则表达式是Linux/Unix系统非常重要的概念。正则表达式(也称为“regex”或“regexp”)是一个可以描述一类字符串的模式(Pattern)。如果一个字符串可以用某个正则表达式来描述,我们就说这个字符和该正则表达式匹配(Match)。这和DOS用户可以使用通配符 “*”代表任意字符类似。在Linux系统上,正则表达式通常被用来查找文本的模式,以及对文本执行“搜索-替换”操作和其它功能。 4.应用实例 查询DNS服务是日常工作之一,这意味着要维护覆盖不同网络的大量IP地址。有时IP地址会超过2000个。如果要查看nnn.nnn网络地址,但是却忘了第二部分的其余部分,只知到有两个句点,例如nnn nn..。要抽取其所有nnn.nnn IP地址,使用[0-9 ]\{3 \}\.[0-0\{3\}\。含义是任意数字出现3次,后跟句点,接着是任意数字出现3次,后跟句点。 $grep '[0-9 ]\{3 \}\.[0-0\{3\}\' ipfile 补充说明,grep家族还包括fgrep和egrep。fgrep是fix grep,允许查找字符串而不是一个模式;egrep是扩展grep,支持基本及扩展的正则表达式,但不支持\q模式范围的应用及与之相对应的一些更加规范的模式。 dd 1.作用 dd命令用来复制文件,并根据参数将数据转换和格式化。 2.格式 dd [options] 3.[opitions]主要参数 bs=字节:强迫 ibs=及obs=。 cbs=字节:每次转换指定的。 conv=关键字:根据以逗号分隔的关键字表示的方式来转换文件。 count=块数目:只复制指定的输入数据。 ibs=字节:每次读取指定的。 if=文件:读取内容,而非标准输入的数据。 obs=字节:每次写入指定的。 of=文件:将数据写入,而不在标准输出显示。 seek=块数目:先略过以obs为单位的指定的输出数据。 skip=块数目:先略过以ibs为单位的指定的输入数据。 4.应用实例 dd命令常常用来制作Linux启动盘。先找一个可引导内核,令它的根设备指向正确的根分区,然后使用dd命令将其写入软盘: $ rdev vmlinuz /dev/hda $dd if=vmlinuz of=/dev/fd0 上面代码说明,使用rdev命令将可引导内核vmlinuz的根设备指向/dev/hda,请把“hda”换成自己的根分区,接下来用dd命令将该内核写入软盘。 find 1.作用 find命令的作用是在目录搜索文件,它的使用权限是所有用户。 2.格式 find [path][options][expression] path指定目录路径,系统从这里开始沿着目录树向下查找文件。它是一个路径列表,相互用空格分离,如果不写path,那么默认为当前目录。 3.主要参数 [options]参数: -depth:使用深度级别的查找过程方式,在某层指定目录优先查找文件内容。 -maxdepth levels:表示至多查找到开始目录的第level层子目录。level是一个非负数,如果level是0的话表示仅在当前目录查找。 -mindepth levels:表示至少查找到开始目录的第level层子目录。 -mount:不在其它文件系统(如Msdos、Vfat等)的目录和文件查找。 -version:打印版本。 [expression]是匹配表达式,是find命令接受的表达式,find命令的所有操作都是针对表达式的。它的参数非常多,这里只介绍一些常用的参数。 —name:支持统配符*和?。 -atime n:搜索在过去n天读取过的文件。 -ctime n:搜索在过去n天修改过的文件。 -group grpoupname:搜索所有组为grpoupname的文件。 -user 用户名:搜索所有文件属主为用户名(ID或名称)的文件。 -size n:搜索文件大小是n个block的文件。 -print:输出搜索结果,并且打印。 4.应用技巧 find命令查找文件的几种方法: (1)根据文件名查找 例如,我们想要查找一个文件名是lilo.conf的文件,可以使用如下命令: find / -name lilo.conf find命令后的“/”表示搜索整个硬盘。 (2)快速查找文件 根据文件名查找文件会遇到一个实际问题,就是要花费相当长的一段时间,特别是大型Linux文件系统和大容量硬盘文件放在很深的子目录时。如果我们知道了这个文件存放在某个目录,那么只要在这个目录往下寻找就能节省很多时间。比如smb.conf文件,从它的文件后缀“.conf”可以判断这是一个配置文件,那么它应该在/etc目录内,此时可以使用下面命令: find /etc -name smb.conf 这样,使用“快速查找文件”方式可以缩短时间。 (3)根据部分文件名查找方法 有时我们知道只某个文件包含有abvd这4个字,那么要查找系统所有包含有这4个字符的文件可以输入下面命令: find / -name '*abvd*' 输入这个命令以后,Linux系统会将在/目录查找所有的包含有abvd这4个字符的文件(其*是通配符),比如abvdrmyz等符合条件的文件都能显示出来。 (4) 使用混合查找方式查找文件 find命令可以使用混合查找的方法,例如,我们想在/etc目录查找大于500000字节,并且在24小时内修改的某个文件,则可以使用-and (与)把两个查找参数链接起来组合成一个混合的查找方式。 find /etc -size +500000c -and -mtime +1 mv 1.作用 mv命令用来为文件或目录改名,或者将文件由一个目录移入另一个目录,它的使用权限是所有用户。该命令如同DOS命令的ren和move的组合。 2.格式 mv[options] 源文件或目录 目标文件或目录 3.[options]主要参数 -i:交互方式操作。如果mv操作将导致对已存在的目标文件的覆盖,此时系统询问是否重写,要求用户回答“y”或“n”,这样可以避免误覆盖文件。 -f:禁止交互操作。mv操作要覆盖某个已有的目标文件时不给任何指示,指定此参数后i参数将不再起作用。 4.应用实例 (1)将/usr/cbu的所有文件移到当前目录(用“.”表示): $ mv /usr/cbu/ * . (2)将文件cjh.txt重命名为wjz.txt: $ mv cjh.txt wjz.txt  ls 1.作用 ls命令用于显示目录内容,类似DOS下的dir命令,它的使用权限是所有用户。 2.格式 ls [options][filename] 3.options主要参数 -a, --all:不隐藏任何以“.” 字符开始的项目。 -A, --almost-all:列出除了“ . ”及 “.. ”以外的任何项目。 --author:印出每个文件著作者。 -b, --escape:以八进制溢出序列表示不可打印的字符。 --block-size=大小:块以指定的字节为单位。 -B, --ignore-backups:不列出任何以 ~ 字符结束的项目。 -f:不进行排序,-aU参数生效,-lst参数失效。 -F, --classify:加上文件类型的指示符号 (*/=@| 其一个)。 -g:like -l, but do not list owner。 -G, --no-group:inhibit display of group information。 -i, --inode:列出每个文件的inode号。 -I, --ignore=样式:不印出任何符合Shell万用字符的项目。 -k:即--block-size=1K。 -l:使用较长格式列出信息。 -L, --dereference:当显示符号链接的文件信息时,显示符号链接所指示的对象,而并非符号链接本身的信息。 -m:所有项目以逗号分隔,并填满整行行宽。 -n, --numeric-uid-gid:类似-l,但列出UID及GID号。 -N, --literal:列出未经处理的项目名称,例如不特别处理控制字符。 -p, --file-type:加上文件类型的指示符号 (/=@| 其一个)。 -Q, --quote-name:将项目名称括上双引号。 -r, --reverse:依相反次序排列。 -R, --recursive:同时列出所有子目录层。 -s, --size:以块大小为序。 4.应用举例 ls 命令是Linux系统使用频率最多的命令,它的参数也是Linux命令最多的。使用ls命令时会有几种不同的颜色,其蓝色表示是目录,绿色表示是可执行文件,红色表示是压缩文件,浅蓝色表示是链接文件,加粗的黑色表示符号链接,灰色表示是其它格式文件。ls最常使用的是ls- l,见图1所示。 图1 使用ls-l命令 文件类型开头是由10个字符构成的字符串。其第一个字符表示文件类型,它可以是下述类型之一:-(普通文件)、d(目录)、l(符号链接)、b(块设备文件)、c(字符设备文件)。后面的9个字符表示文件的访问权限,分为3组,每组3位。第一组表示文件属主的权限,第二组表示同组用户的权限,第三组表示其他用户的权限。每一组的三个字符分别表示对文件的读(r)、写(w)和执行权限(x)。对于目录,表示进入权限。s表示当文件被执行时,把该文件的UID 或GID赋予执行进程的UID(用户ID)或GID(组 ID)。t表示设置标志位(留在内存,不被换出)。如果该文件是目录,那么在该目录的文件只能被超级用户、目录拥有者或文件属主删除。如果它是可执行文件,那么在该文件执行后,指向其正文段的指针仍留在内存。这样再次执行它时,系统就能更快地装入该文件。接着显示的是文件大小、生成时间、文件或命令名称。 diff 1.作用 diff命令用于两个文件之间的比较,并指出两者的不同,它的使用权限是所有用户。 2.格式 diff [options] 源文件 目标文件 3.[options]主要参数 -a:将所有文件当作文本文件来处理。 -b:忽略空格造成的不同。 -B:忽略空行造成的不同。 -c:使用纲要输出格式。 -H:利用试探法加速对大文件的搜索。 -I:忽略大小写的变化。 -n --rcs:输出RCS格式。 cmp 1.作用 cmp(“compare”的缩写)命令用来简要指出两个文件是否存在差异,它的使用权限是所有用户。 2.格式 cmp[options] 文件名 3.[options]主要参数 -l: 将字节以十进制的方式输出,并方便将两个文件不同的以八进制的方式输出。 cat 1.作用 cat(“concatenate”的缩写)命令用于连接并显示指定的一个和多个文件的有关信息,它的使用权限是所有用户。 2.格式 cat [options] 文件1 文件2…… 3.[options]主要参数 -n:由第一行开始对所有输出的行数编号。 -b:和-n相似,只不过对于空白行不编号。 -s:当遇到有连续两行以上的空白行时,就代换为一行的空白行。 4.应用举例 (1)cat命令一个最简单的用处是显示文本文件的内容。例如,我们想在命令行看一下README文件的内容,可以使用命令: $ cat README  (2)有时需要将几个文件处理成一个文件,并将这种处理的结果保存到一个单独的输出文件。cat命令在其输入上接受一个或多个文件,并将它们作为一个单独的文件打印到它的输出。例如,把README和INSTALL的文件内容加上行号(空白行不加)之后,将内容附加到一个新文本文件File1 : $ cat README INSTALL File1 (3)cat还有一个重要的功能就是可以对行进行编号,见图2所示。这种功能对于程序文档的编制,以及法律和科学文档的编制很方便,打印在左边的行号使得参考文档的某一部分变得容易,这些在编程、科学研究、业务报告甚至是立法工作都是非常重要的。 图2 使用cat命令/etc/named.conf文件进行编号 对行进行编号功能有-b(只能对非空白行进行编号)和-n(可以对所有行进行编号)两个参数: $ cat -b /etc/named.conf ln 1.作用 ln命令用来在文件之间创建链接,它的使用权限是所有用户。 2.格式 ln [options] 源文件 [链接名] 3.参数 -f:链结时先将源文件删除。 -d:允许系统管理者硬链结自己的目录。 -s:进行软链结(Symbolic Link)。 -b:将在链结时会被覆盖或删除的文件进行备份。 链接有两种,一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link)。默认情况下,ln命令产生硬链接。 硬连接指通过索引节点来进行的连接。在Linux的文件系统,保存在磁盘分区的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件才会被真正删除。 与硬连接相对应,Lnux系统还存在另一种连接,称为符号连接(Symbilc Link),也叫软连接。软链接文件有点类似于Windows的快捷方式。它实际上是特殊文件的一种。在符号连接,文件实际上是一个文本文件,其包含的有另一文件的位置信息。 动手练习 上面我们介绍了Linux文件处理命令,下面介绍几个实例,大家可以动手练习一下刚才讲过的命令。 1.利用符号链接快速访问关键目录 符号链接是一个非常实用的功能。假设有一些目录或文件需要频繁使用,但由于Linux的文件和目录结构等原因,这个文件或目录在很深的子目录。比如, Apache Web服务器文档位于系统的/usr/local/httpd/htdocs,并且不想每次都要从主目录进入这样一个长的路径之(实际上,这个路径也非常不容易记忆)。 为了解决这个问题,可以在主目录创建一个符号链接,这样在需要进入该目录时,只需进入这个链接即可。 为了能方便地进入Web服务器(/usr/local/httpd/htdocs)文档所在的目录,在主目录下可以使用以下命令: $ ln -s /usr/local/httpd/htdocs gg 这样每次进入gg目录就可访问Web服务器的文档,以后如果不再访问Web服务器的文档时,删除gg即可,而真正的Web服务器的文档并没有删除。 2.使用dd命令将init.rd格式的root.ram内容导入内存 dd if=/dev/fd0 of=floppy.fd dd if=root.ram of=/dev/ram0 # 3.grep命令系统调用 grep是Linux/Unix使用最广泛的命令之一,许多Linux系统内部都可以调用它。 (1)如果要查询目录列表的目录,方法如下: $ ls -l | grep '∧d' (2)如果在一个目录查询不包含目录的所有文件,方法如下: $ ls -l | grep '∧[∧d]' (3)用find命令调用grep,如所有C源代码的“Chinput”,方法如下: $find /ZhXwin -name *.c -exec grep -q -s Chinput {} \;-print -------------------------------------------------------------------------------- Linux必学的60个命令(3)-系统管理命令 Linux必学的系统管理命令 对于Linux系统来说,无论是央处理器、内存、磁盘驱动器、键盘、鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心。熟悉了Linux常用的文件处理命令以后,这一讲介绍对系统和用户进行管理的命令。 df 1.作用 df命令用来检查文件系统的磁盘空间占用情况,使用权限是所有用户。 2.格式 df [options] 3.主要参数 -s:对每个Names参数只给出占用的数据块总数。 -a:递归地显示指定目录各文件及子目录各文件占用的数据块数。若既不指定-s,也不指定-a,则只显示Names的每一个目录及其的各子目录所占的磁盘块数。 -k:以1024字节为单位列出磁盘空间使用情况。 -x:跳过在不同文件系统上的目录不予统计。 -l:计算所有的文件大小,对硬链接文件则计算多次。 -i:显示inode信息而非块使用量。 -h:以容易理解的格式印出文件系统大小,例如136KB、254MB、21GB。 -P:使用POSIX输出格式。 -T:显示文件系统类型。 4.说明 df命令被广泛地用来生成文件系统的使用统计数据,它能显示系统所有的文件系统的信息,包括总容量、可用的空闲空间、目前的安装点等。 超级权限用户使用df命令时会发现这样的情况:某个分区的容量超过了100%。这是因为Linux系统为超级用户保留了10%的空间,由其单独支配。也就是说,对于超级用户而言,他所见到的硬盘容量将是110%。这样的安排对于系统管理而言是有好处的,当硬盘被使用的容量接近100%时系统管理员还可以正常工作。 5.应用实例 Linux支持的文件系统非常多,包括JFS、ReiserFS、ext、ext2、ext3、ISO9660、XFS、Minx、vfat、MSDOS等。使用df -T命令查看磁盘空间时还可以得到文件系统的信息: #df -T 文件系统 类型 容量 已用 可用 已用% 挂载点 /dev/hda7 reiserfs 5.2G 1.6G 3.7G 30% / /dev/hda1 vfat 2.4G 1.6G 827M 66% /windows/C /dev/hda5 vfat 3.0G 1.7G 1.3G 57% /windows/D /dev/hda9 vfat 3.0G 2.4G 566M 82% /windows/E /dev/hda10 NTFS 3.2G 573M 2.6G 18% /windows/F /dev/hda11 vfat 1.6G 1.5G 23M 99% /windows/G 从上面除了可以看到磁盘空间的容量、使用情况外,分区的文件系统类型、挂载点等信息也一览无遗。 top 1.作用 top命令用来显示执行的程序进程,使用权限是所有用户。 2.格式 top [-] [d delay] [q] [c] [S] [s] [i] [n] 3.主要参数 d:指定更新的间隔,以秒计算。 q:没有任何延迟的更新。如果使用者有超级用户,则top命令将会以最高的优先序执行。 c:显示进程完整的路径与名称。 S:累积模式,会将己完成或消失的子行程的CPU时间累积起来。 s:安全模式。 i:不显示任何闲置(Idle)或无用(Zombie)的行程。 n:显示更新的次数,完成后将会退出top。 4.说明 top命令是Linux系统管理的一个主要命令,通过它可以获得许多信息。这里我们结合图1来说明它给出的信息。 图1 top命令的显示 在图1,第一行表示的项目依次为当前时间、系统启动时间、当前系统登录用户数目、平均负载。第二行显示的是所有启动的进程、目前运行的、挂起 (Sleeping)的和无用(Zombie)的进程。第三行显示的是目前CPU的使用情况,包括系统占用的比例、用户使用比例、闲置(Idle)比例。第四行显示物理内存的使用情况,包括总的可以使用的内存、已用内存、空闲内存、缓冲区占用的内存。第五行显示交换分区使用情况,包括总的交换分区、使用的、空闲的和用于高速缓存的大小。第六行显示的项目最多,下面列出了详细解释。 PID(Process ID):进程标示号。 USER:进程所有者的用户名。 PR:进程的优先级别。 NI:进程的优先级别数值。 VIRT:进程占用的虚拟内存值。 RES:进程占用的物理内存值。 SHR:进程使用的共享内存值。 S:进程的状态,其S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值是负数。 %CPU:该进程占用的CPU使用率。 %MEM:该进程占用的物理内存和总内存的百分比。 TIME+:该进程启动后占用的总的CPU时间。 Command:进程启动的启动命令名称,如果这一行显示不下,进程会有一个完整的命令行。 top命令使用过程,还可以使用一些交互的命令来完成其它参数的功能。这些命令是通过快捷键启动的。 :立刻刷新。 P:根据CPU使用大小进行排序。 T:根据时间、累计时间排序。 q:退出top命令。 m:切换显示内存信息。 t:切换显示进程和CPU状态信息。 c:切换显示命令名称和完整命令行。 M:根据使用内存大小进行排序。 W:将当前设置写入~/.toprc文件。这是写top配置文件的推荐方法。 可以看到,top命令是一个功能十分强大的监控系统的工具,对于系统管理员而言尤其重要。但是,它的缺点是会消耗很多系统资源。 5.应用实例 使用top命令可以监视指定用户,缺省情况是监视所有用户的进程。如果想查看指定用户的情况,在终端按“U”键,然后输入用户名,系统就会切换为指定用户的进程运行界面,见图2所示。 图2 使用top命令监视指定用户 free 1.作用 free命令用来显示内存的使用情况,使用权限是所有用户。 2.格式 free [-b|-k|-m] [-o] [-s delay] [-t] [-V] 3.主要参数 -b -k -m:分别以字节(KB、MB)为单位显示内存使用情况。 -s delay:显示每隔多少秒数来显示一次内存使用情况。 -t:显示内存总和列。 -o:不显示缓冲区调节列。 4.应用实例 free命令是用来查看内存使用情况的主要命令。和top命令相比,它的优点是使用简单,并且只占用很少的系统资源。通过-S参数可以使用free命令不间断地监视有多少内存在使用,这样可以把它当作一个方便实时监控器。 #free -b -s5 使用这个命令后终端会连续不断地报告内存使用情况(以字节为单位),每5秒更新一次。 quota 1.作用 quota命令用来显示磁盘使用情况和限制情况,使用权限超级用户。 2.格式 quota [-g][-u][-v][-p] 用户名 组名 3.参数 -g:显示用户所在组的磁盘使用限制。 -u:显示用户的磁盘使用限制。 -v:显示没有分配空间的文件系统的分配情况。 -p:显示简化信息。 4.应用实例 在企业应用磁盘配额非常重要,普通用户要学会看懂自己的磁盘使用情况。要查询自己的磁盘配额可以使用下面命令(下例用户账号是caojh): #quota caojh Disk quotas for user caojh(uid 502): Filesystem blocks quota limit grace files quota limit grace /dev/hda3 58 200000 400000 41 500 1000 以上显示ID号为502的caojh账号,文件个数设置为500~1000个,硬盘空间限制设置为200MB~400MB。一旦磁盘配额要用完时,就需要删除一些垃圾文件或向系统管理员请求追加配额。 at 1.作用 at命令用来在指定时刻执行指定的命令序列。 2.格式 at [-V] [-q x] [-f file] [-m] time 3.主要参数 -V:显示标准错误输出。 -q:许多队列输出。 -f:从文件读取作业。 -m:执行完作业后发送电子邮件到用户。 time:设定作业执行的时间。time格式有严格的要求,由小时、分钟、日期和时间的偏移量组成,其日期的格式为MM.DD.YY,MM是分钟,DD是日期,YY是指年份。偏移量的格式为时间+偏移量,单位是minutes、hours和days。 4.应用实例 #at -f data 15:30 +2 days 上面命令表示让系统在两天后的17:30执行文件data指明的作业。 lp 1.作用 lp是打印文件的命令,使用权限是所有用户。 2.格式 lp [-c][-d][-m][-number][-title][-p] 3.主要参数 -c:先拷贝文件再打印。 -d:打印队列文件。 -m:打印结束后发送电子邮件到用户。 -number:打印份数。 -title:打印标题。 -p:设定打印的优先级别,最高为100。 4.应用实例 (1)使用lp命令打印多个文件 #lp 2 3 4 request id is 11 (3 file(s)) 其2、3、4分别是文件名;“request id is 11 (3 file(s)) ”表示这是第11个打印命令,依次打印这三个文件。 (2)设定打印优先级别 #lp lp -d LaserJet -p 90 /etc/aliases 通过添加“-p 90”,规定了打印作业的优先级为90。它将在优先级低于90的打印作业之前打印,包括没有设置优先级的作业,缺省优先级是50 useradd 1.作用 useradd命令用来建立用户帐号和创建用户的起始目录,使用权限是超级用户。 2.格式 useradd [-d home] [-s shell] [-c comment] [-m [-k template]] [-f inactive] [-e expire ] [-p passwd] [-r] name 3.主要参数 -c:加上备注文字,备注文字保存在passwd的备注栏。  -d:指定用户登入时的启始目录。 -D:变更预设值。 -e:指定账号的有效期限,缺省表示永久有效。 -f:指定在密码过期后多少天即关闭该账号。 -g:指定用户所属的群组。 -G:指定用户所属的附加群组。 -m:自动建立用户的登入目录。 -M:不要自动建立用户的登入目录。 -n:取消建立以用户名称为名的群组。 -r:建立系统账号。 -s:指定用户登入后所使用的shell。 -u:指定用户ID号。 4.说明 useradd可用来建立用户账号,它和adduser命令是相同的。账号建好之后,再用passwd设定账号的密码。使用useradd命令所建立的账号,实际上是保存在/etc/passwd文本文件。 5.应用实例 建立一个新用户账户,并设置ID: #useradd caojh -u 544 需要说明的是,设定ID值时尽量要大于500,以免冲突。因为Linux安装后会建立一些特殊用户,一般0到499之间的值留给bin、mail这样的系统账号。 groupadd 1.作用 groupadd命令用于将新组加入系统。 2.格式 groupadd [-g gid] [-o]] [-r] [-f] groupname 3.主要参数 -g gid:指定组ID号。 -o:允许组ID号,不必惟一。 -r:加入组ID号,低于499系统账号。 -f:加入已经有的组时,发展程序退出。 4.应用实例 建立一个新组,并设置组ID加入系统: #groupadd -g 344 cjh 此时在/etc/passwd文件产生一个组ID(GID)是344的项目。 kill 1.作用 kill命令用来止一个进程。 2.格式 kill [ -s signal | -p ] [ -a ] pid ... kill -l [ signal ] 3.参数 -s:指定发送的信号。 -p:模拟发送信号。 -l:指定信号的名称列表。 pid:要止进程的ID号。 Signal:表示信号。 4.说明 进程是Linux系统一个非常重要的概念。Linux是一个多任务的操作系统系统上经常同时运行着多个进程。我们不关心这些进程究竟是如何分配的,或者是内核如何管理分配时间片的,所关心的是如何去控制这些进程,让它们能够很好地为用户服务。 Linux 操作系统包括三种不同类型的进程,每种进程都有自己的特点和属性。交互进程是由一个Shell启动的进程。交互进程既可以在前台运行,也可以在后台运行。批处理进程和终端没有联系,是一个进程序列。监控进程(也称系统守护进程)时Linux系统启动时启动的进程,并在后台运行。例如,httpd是著名的 Apache服务器的监控进程。 kill命令的工作原理是,向Linux系统的内核发送一个系统操作信号和某个程序的进程标识号,然后系统内核就可以对进程标识号指定的进程进行操作。比如在top命令,我们看到系统运行许多进程,有时就需要使用kill止某些进程来提高系统资源。在讲解安装和登陆命令时,曾提到系统多个虚拟控制台的作用是当一个程序出错造成系统死锁时,可以切换到其它虚拟控制台工作关闭这个程序。此时使用的命令就是kill,因为kill是大多数Shell内部命令可以直接调用的。 5.应用实例 (1)强行止(经常使用杀掉)一个进程标识号为324的进程: #kill -9 324 (2)解除Linux系统的死锁 在Linux 有时会发生这样一种情况:一个程序崩溃,并且处于死锁的状态。此时一般不用重新启动计算机,只需要止(或者说是关闭)这个有问题的程序即可。当 kill处于X-Window界面时,主要的程序(除了崩溃的程序之外)一般都已经正常启动了。此时打开一个终端,在那里止有问题的程序。比如,如果 Mozilla浏览器程序出现了锁死的情况,可以使用kill命令来止所有包含有Mozolla浏览器的程序。首先用top命令查处该程序的PID,然后使用kill命令停止这个程序: #kill -SIGKILL XXX 其,XXX是包含有Mozolla浏览器的程序的进程标识号。 (3)使用命令回收内存 我们知道内存对于系统是非常重要的,回收内存可以提高系统资源。kill命令可以及时地止一些“越轨”的程序或很长时间没有相应的程序。例如,使用top命令发现一个无用 (Zombie) 的进程,此时可以使用下面命令: #kill -9 XXX 其,XXX是无用的进程标识号。 然后使用下面命令: #free 此时会发现可用内存容量增加了。 (4)killall命令 Linux下还提供了一个killall命令,可以直接使用进程的名字而不是进程标识号,例如: # killall -HUP inetd crontab 1.作用 使用crontab命令可以修改crontab配置文件,然后该配置由cron公用程序在适当的时间执行,该命令使用权限是所有用户。 2.格式 crontab [ -u user ] 文件 crontab [ -u user ] { -l | -r | -e } 3.主要参数 -e:执行文字编辑器来设定时程表,内定的文字编辑器是vi。 -r:删除目前的时程表。 -l:列出目前的时程表。 crontab 文件的格式为“M H D m d cmd”。其,M代表分钟(0~59),H代表小时(0~23),D代表天(1~31),m代表月(1~12),d代表一星期内的天(0~6,0为星期天)。cmd表示要运行的程序,它被送入sh执行,这个Shell只有USER、HOME、SHELL三个环境变量。 4.说明 和at命令相比,crontab命令适合完成固定周期的任务。 5.应用实例 设置一个定时、定期的系统提示: [cao @www cao]#crontab -e 此时系统会打开一个vi编辑器。 如果输入以下内容:35 17 * * 5 wall "Tomorrow is Saturday I will go CS",然后存盘退出。这时在/var/spool/cron/目录下会生产一个cao的文件,内容如下: # DO NOT EDIT THIS FILE - edit the master and reinstall. # (/tmp/crontab.2707 installed on Thu Jan 1 22:01:51 2004) # (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $) 35 17 * * 5 wall "Tomorrow is Saturday I will play CS " 这样每个星期五17:35系统就会弹出一个终端,提醒星期六可以打打CS了!显示结果见图3所示。 图3 一个定时、定期的系统提示 动手练习 1.联合使用kill和top命令观察系统性能的变化 首先启动一个终端运行top命令,然后再启动一个终端使用kill命令,见图4所示。 图4 观察kill命令对top终端的影响 这时利用上面介绍的kill命令来止一些程序: #kill SIGKILL XXX 然后再看top命令终端的变化,包括内存容量、CPU使用率、系统负载等。注意,有些进程是不能止的,不过学习Linux命令时可以试试,看看系统有什么反应。 2.使用at和halt命令定时关机 首先设定关机时间是17:35,输入下面代码: #at 17:35 warning: commands will be executed using (in order) a) $SHELL b) login shell c) /bin/sh at>halt `-i -p at> job 6 at 2004-01-01 17:35 此时实际上就已经进入Linux系统的Shell,并且编写一个最简单程序:halt -i -p。上面Shell的文本结束符号表示按“Ctrl+D”组合键关闭命令,提交任务退出Shell。“Job 6 at 2004-01-01 17:35”表示系统接受第6个at命令,在“2004-01-01 17:35”时执行命令:先把所有网络相关的装置停止,关闭系统后关闭电源。 3.用crontab命令实现每天定时的病毒扫描 前面已经介绍了一个简单的crontab命令操作,这里看一些更重要的操作。 (1)建立一个文件,文件名称自己设定,假设为caoproject: #crontab -e (2)文件内容如下: 05 09 * * * antivir 用vi编辑后存盘退出。antivir是一个查杀Linux病毒的软件,当然需要时先安装在系统。 (3)使用crontab命令添加到任务列表: #crontab caoproject 这样系统内所有用户在每天的9点05分会自动进行病毒扫描。 4.用kill使修改的配置文件马上生效 Windows用户一般都知道,重要配置文件修改后往往都要重新启动计算机才能使修改生效。而Linux由于采用了模块化设计,可以自己根据需要实时设定服务。这里以网络服务inetd为例介绍一些操作技巧。 inetd 是一个监听守护进程,监听与提供互联网服务进程(如rlogin、telnet、ftp、rsh)进行连接的要求,并扩展所需的服务进程。默认情况下, inetd监听的这些daemon均列于/etc /inetd.conf文件。编辑/etc/inetd.conf文件,可以改变inetd启动服务器守护进程的选项,然后驱使inetd以 SIGHUP(signal 1)向当前的inetd进程发送信号,使inetd重读该文件。这一过程由kill命令来实现。 用vi或其它编辑器修改inetd.conf后,首先使用下面命令: #ps -ef |grep inetd 上面代码表明查询inetd.conf的进程号(PID),这里假设是1426,然后使用下面命令: # kill -1426 inetd 这样配置文件就生效了。 这一讲介绍的系统管理命令都是比较重要的,特别是crontab命令和quota命令使用起来会有一定难度,需要多做一些练习。另外,使用kill命令要注意“-9“这个参数,练习时最好不要运行一些重要的程序。 -------------------------------------------------------------------------------- Linux必学的60个命令(4)-网络操作命令 Linux必学的60个命令:网络操作命令 因为Linux系统是在Internet上起源和发展的,它与生俱来拥有强大的网络功能和丰富的网络应用软件,尤其是TCP/IP网络协议的实现尤为成熟。 Linux的网络命令比较多,其一些命令像ping、 ftp、telnet、route、netstat等在其它操作系统上也能看到,但也有一些Unix/Linux系统独有的命令,如ifconfig、 finger、mail等。Linux网络操作命令的一个特点是,命令参数选项和功能很多,一个命令往往还可以实现其它命令的功能。 ifconfig 1.作用 ifconfig用于查看和更改网络接口的地址和参数,包括IP地址、网络掩码、广播地址,使用权限是超级用户。 2.格式 ifconfig -interface [options] address 3.主要参数 -interface:指定的网络接口名,如eth0和eth1。 up:激活指定的网络接口卡。 down:关闭指定的网络接口。 broadcast address:设置接口的广播地址。 pointopoint:启用点对点方式。 address:设置指定接口设备的IP地址。 netmask address:设置接口的子网掩码。 4.应用说明 ifconfig是用来设置和配置网卡的命令行工具。为了手工配置网络,这是一个必须掌握的命令。使用该命令的好处是无须重新启动机器。要赋给eth0接口IP地址207.164.186.2,并且马上激活它,使用下面命令: #fconfig eth0 210.34.6.89 netmask 255.255.255.128 broadcast 210.34.6.127 该命令的作用是设置网卡eth0的IP地址、网络掩码和网络的本地广播地址。若运行不带任何参数的ifconfig命令,这个命令将显示机器所有激活接口的信息。带有“-a”参数的命令则显示所有接口的信息,包括没有激活的接口。注意,用ifconfig命令配置的网络设备参数,机器重新启动以后将会丢失。 如果要暂停某个网络接口的工作,可以使用down参数: #ifconfig eth0 down ip 1.作用 ip是iproute2软件包里面的一个强大的网络配置工具,它能够替代一些传统的网络管理工具,例如ifconfig、route等,使用权限为超级用户。几乎所有的Linux发行版本都支持该命令。 2.格式 ip [OPTIONS] OBJECT [COMMAND [ARGUMENTS]] 3.主要参数 OPTIONS是修改ip行为或改变其输出的选项。所有的选项都是以-字符开头,分为长、短两种形式。目前,ip支持如表1所示选项。 OBJECT是要管理者获取信息的对象。目前ip认识的对象见表2所示。 表1 ip支持的选项 -V,-Version 打印ip的版本并退出。 -s,-stats,-statistics 输出更为详尽的信息。如果这个选项出现两次或多次,则输出的信息将更为详尽。 -f,-family 这个选项后面接协议种类,包括inet、inet6或link,强调使用的协议种类。如果没有足够的信息告诉ip使用的协议种类,ip就会使用默认值inet或any。link比较特殊,它表示不涉及任何网络协议。 -4 是-family inet的简写。 -6 是-family inet6的简写。 -0 是-family link的简写。 -o,-oneline 对每行记录都使用单行输出,回行用字符代替。如果需要使用wc、grep等工具处理ip的输出,则会用到这个选项。 -r,-resolve 查询域名解析系统,用获得的主机名代替主机IP地址 COMMAND 设置针对指定对象执行的操作,它和对象的类型有关。一般情况下,ip支持对象的增加(add)、删除(delete)和展示(show或list)。有些对象不支持这些操作,或者有其它的一些命令。对于所有的对象,用户可以使用help命令获得帮助。这个命令会列出这个对象支持的命令和参数的语法。如果没有指定对象的操作命令,ip会使用默认的命令。一般情况下,默认命令是list,如果对象不能列出,就会执行help命令。 ARGUMENTS 是命令的一些参数,它们倚赖于对象和命令。ip支持两种类型的参数:flag和parameter。flag由一个关键词组成;parameter由一个关键词加一个数值组成。为了方便,每个命令都有一个可以忽略的默认参数。例如,参数dev是ip link命令的默认参数,因此ip link ls eth0等于ip link ls dev eth0。我们将在后面的详细介绍每个命令的使用,命令的默认参数将使用default标出。 4.应用实例 添加IP地址192.168.2.2/24到eth0网卡上: #ip addr add 192.168.1.1/24 dev eth0 丢弃源地址属于192.168.2.0/24网络的所有数据报: #ip rule add from 192.168.2.0/24 prio 32777 reject ping 1.作用 ping检测主机网络接口状态,使用权限是所有用户。 2.格式 ping [-dfnqrRv][-c][-i][-I][-l][-p][-s][-t] IP地址 3.主要参数 -d:使用Socket的SO_DEBUG功能。 -c:设置完成要求回应的次数。 -f:极限检测。 -i:指定收发信息的间隔秒数。 -I:网络界面使用指定的网络界面送出数据包。 -l:前置载入,设置在送出要求信息之前,先行发出的数据包。 -n:只输出数值。 -p:设置填满数据包的范本样式。 -q:不显示指令执行过程,开头和结尾的相关信息除外。 -r:忽略普通的Routing Table,直接将数据包送到远端主机上。 -R:记录路由过程。 -s:设置数据包的大小。 -t:设置存活数值TTL的大小。 -v:详细显示指令的执行过程。 ping 命令是使用最多的网络指令,通常我们使用它检测网络是否连通,它使用ICMP协议。但是有时会有这样的情况,我们可以浏览器查看一个网页,但是却无法 ping通,这是因为一些网站处于安全考虑安装了防火墙。另外,也可以在自己计算机上试一试,通过下面的方法使系统对ping没有反应: # echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all netstat 1.作用 检查整个Linux网络状态。 2.格式 netstat [-acCeFghilMnNoprstuvVwx][-A][--ip] 3.主要参数 -a--all:显示所有连线的Socket。 -A:列出该网络类型连线的IP相关地址和网络类型。 -c--continuous:持续列出网络状态。 -C--cache:显示路由器配置的快取信息。 -e--extend:显示网络其它相关信息。 -F--fib:显示FIB。 -g--groups:显示多重广播功能群组组员名单。 -h--help:在线帮助。 -i--interfaces:显示网络界面信息表单。 -l--listening:显示监控的服务器的Socket。 -M--masquerade:显示伪装的网络连线。 -n--numeric:直接使用IP地址,而不通过域名服务器。 -N--netlink--symbolic:显示网络硬件外围设备的符号连接名称。 -o--timers:显示计时器。 -p--programs:显示正在使用Socket的程序识别码和程序名称。 -r--route:显示Routing Table。 -s--statistice:显示网络工作信息统计表。 -t--tcp:显示TCP传输协议的连线状况。 -u--udp:显示UDP传输协议的连线状况。 -v--verbose:显示指令执行过程。 -V--version:显示版本信息。 -w--raw:显示RAW传输协议的连线状况。 -x--unix:和指定“-A unix”参数相同。 --ip--inet:和指定“-A inet”参数相同。 4.应用实例 netstat 主要用于Linux察看自身的网络状况,如开启的端口、在为哪些用户服务,以及服务的状态等。此外,它还显示系统路由表、网络接口状态等。可以说,它是一个综合性的网络状态的察看工具。在默认情况下,netstat只显示已建立连接的端口。如果要显示处于监听状态的所有端口,使用-a参数即可: #netstat -a Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 *:32768 *:* LISTEN tcp 0 0 *:32769 *:* LISTEN tcp 0 0 *:nfs *:* LISTEN tcp 0 0 *:32770 *:* LISTEN tcp 0 0 *:868 *:* LISTEN tcp 0 0 *:617 *:* LISTEN tcp 0 0 *:mysql *:* LISTEN tcp 0 0 *:netbios-ssn *:* LISTEN tcp 0 0 *:sunrpc *:* LISTEN tcp 0 0 *:10000 *:* LISTEN tcp 0 0 *:http *:* LISTEN ...... 上面显示出,这台主机同时提供HTTP、FTP、NFS、MySQL等服务。 telnet 1.作用 telnet表示开启终端机阶段作业,并登入远端主机。telnet是一个Linux命令,同时也是一个协议(远程登陆协议)。 2.格式 telnet [-8acdEfFKLrx][-b][-e][-k][-l][-n][-S][-X][主机名称IP地址] 3.主要参数 -8:允许使用8位字符资料,包括输入与输出。 -a:尝试自动登入远端系统。 -b:使用别名指定远端主机名称。 -c:不读取用户专属目录里的.telnetrc文件。 -d:启动排错模式。 -e:设置脱离字符。 -E:滤除脱离字符。 -f:此参数的效果和指定“-F”参数相同。 -F:使用Kerberos V5认证时,加上此参数可把本地主机的认证数据上传到远端主机。 -k:使用Kerberos认证时,加上此参数让远端主机采用指定的领域名,而非该主机的域名。 -K:不自动登入远端主机。 -l:指定要登入远端主机的用户名称。 -L:允许输出8位字符资料。 -n:指定文件记录相关信息。 -r:使用类似rlogin指令的用户界面。 -S:服务类型,设置telnet连线所需的IP TOS信息。 -x:假设主机有支持数据加密的功能,就使用它。 -X:关闭指定的认证形态。 4.应用说明 用户使用telnet命令可以进行远程登录,并在远程计算机之间进行通信。用户通过网络在远程计算机上登录,就像登录到本地机上执行命令一样。为了通过 telnet登录到远程计算机上,必须知道远程机上的合法用户名和口令。虽然有些系统确实为远程用户提供登录功能,但出于对安全的考虑,要限制来宾的操作权限,因此,这种情况下能使用的功能是很少的。 t
11 1 1 ---一段引言(几句话) 计算机能够平稳运行,离不开计算机的硬件系统和相应的软件系统。硬件系统,又可以分为输入设备和输出设备,软件系统又分为系统软件和应用软件。 (1)---介绍存储器子系统(可以展开讲存储器体系结构,比如内存,外存,cache,rom, ram等等) 计算机存储系统,分为内存储器和外存储器,其内存器从功能上可以分为:读写存储器 RAM、只读存储器ROM两大类;外存储器有U盘、移动硬盘以及光盘。 RoM:ROM表示只读存储器(Read Only Memory),在制造ROM的时候,信息(数据或程序)就被存入并永久保存。这些信息只能读出,一般不能写入,即使机器停电,这些数据也不会丢失。ROM一般用于存放计算机的基本程序和数据,如BIOS ROM。其物理外形一般是双列直插式(DIP)的集成块。 Cache:高速缓存。我们知道,电脑的内存是以系统总线的时钟频率工作的,这个频率通常也就是CPU的外频。但是,CPU的工作频率(主频)是外频与倍频因子的乘积。Cache是一种特殊的存储器,它由Cache 存储部件和Cache控制部件组成。Cache 控制器部件包括主存地址寄存器、Cache 地址寄存器,主存-Cache地址变换部件及替换控制部件等。CPU运行程序是一条指令一条指令地执行的,而且指令地址往往是连续的,意思就是说CPU在访问内存时,在较短的一段时间内往往集于某个局部,这时候可能会碰到一些需要反复调用的子程序。电脑在工作时,把这些活跃的子程序存入比内存快得多的Cache 。CPU在访问内存时,首先判断所要访问的内容是否在Cache,如果在,就称为"命",此时CPU直接从Cache调用该内容;否则,就称为"不命",CPU只好去内存调用所需的子程序或指令了。CPU不但可以直接从Cache读出内容,也可以直接往其写入内容。由于Cache的存取速率相当快,使得CPU的利用率大大提高,进而使整个系统的性能得以提升。 RAM(random access memory)随机存储器。存储单元的内容可按需随意取出或存入,且存取的速度与存储单元的位置无关的存储器。 按照存储信息的不同,随机存储器又分为静态随机存储器(Static RAM,SRAM)和动态随机存储器(Dynamic RAM,DRAM)。一个DRAM的存储单元存储的是0还是1取决于电容是否有电荷,有电荷代表1,无电荷代表0。但时间一长,代表1的电容会放电,代表0的电容会吸收电荷,这就是数据丢失的原因;刷新操作定期对电容进行检查,若电量大于满电量的1/2,则认为其代表1,并把电容充满电;若电量小于1/2,则认为其代表0,并把电容放电,藉此来保持数据的连续性。 ---介绍CPU子系统(概括性的就可以,几句话) CPU火柴盒大小的体积上,布满了数以万计的晶体管,他们彼此独立又相互关联,CPU内部按照功能区域划分,分别为控制单元(Control Unit;CU)、逻辑单元(Arithmetic Logic Unit;ALU)、存储单元(Memory Unit;MU)三个重要单元。按照CPU内部结构划分,分别为定点运算单元,浮点运算单元,MMX单元,L1 Cache单元和寄存器等。 ---介绍IO子系统 ---介绍软件系统(分系统软件,用户软件) 计算机软件分为系统软件和用户软件。其系统软件最重要且最基本的就是操作系统(OS)。它是最底层的软件,它控制所有计算机运行的程序并管理整个计算机的资源,是计算机裸机与应用程序及用户之间的桥梁。没有它,用户也就无法使用某种软件或程序。 1.操作系统 是计算机系统的控制和管理心,从资源角度来看,它具有处理机、存储器管理、设备管理、文件管理等4项功能。 2.程序语言设计 计算机解题的一般过程是:用户用计算机语言编写程序,输入计算机,然后由计算机将其翻译成机器语言,在计算机上运行后输出结果。程序设计语言的发展经历了五代——机器语言、汇编语言、高级语言、非过程化语言和智能语言。 3.语言处理程序 计算机只能直接识别和执行机器语言,因此要计算机上运行高级语言程序就必须配备程序语言翻译程序,翻译程序本身是一组程序,不同的高级语言都有相应的翻译程序。 4.数据库管理程序 数据库管理系统是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库。 5.系统辅助处理程序 系统辅助处理程序也称为"软件研制开发工具"、"支持软件"、"软件工具",主要有编辑程序、调试程序、装备和连接程序、调试程序。 其:操作系统如我们常用的Windows,linux,Dos,unix mac等。 语言处理程序如汇编语言汇编器,C语言编译、连接器等, 一般来讲,系统软件包括操作系统和一系列基本的工具(比如编译器,数据库管理,存储器格式化

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值