带你读《Linux哲学》之三:数据流

点击这里查看第一章:Linux哲学简介
点击这里查看第二章:准备

第二部分

基  础
■第3章 数据流
■第4章 转换数据流
■第5章 一切都是文件
■第6章 使用Linux FHS
Linux命令行有很多功能,用户可以充分利用它做许多事情。当今的图形用户界面(GUI)使得某些人无须使用命令行,对于许多只想使用一些相对简单的工具来浏览网页、使用电子邮件以及阅读或书写文档的人来说,确实如此。大多数Linux用户无法想象GUI背后隐藏的力量。然而,与其他情况相比,允许更多用户轻松访问计算机功能的GUI隐藏了这台计算机为我们提供的大部分功能。
有一类人特别倾向于成为命令行的主要用户:系统管理员,即负责管理系统的人员。系统管理员是命令行的最终用户,因为命令行可以直接访问全部范围的功能。
这并不是说普通的非root用户不使用命令行。许多人都会使用命令行,但通常是在GUI没有满足他们需求的能力时才这样做。大多数Linux发行版都有用于安装程序、管理用户和组及其权限、移动和管理文件、处理邮件、浏览网页、管理进程和CPU功能、限制某些用户访问系统资源,以及更多功能的图形工具。但是,如果命令行界面(CLI)的临时用户深入探索下去,他们会发现Linux提供了许多文本模式和命令行工具来执行可以在GUI中执行的每项任务和不能用GUI完成的许多任务,而且通常运行速度更快,功能更多。
作为系统管理员,我的需求包括功能、速度、灵活性和对操作系统的完全控制。满足所有这些需求的唯一方法是不受限制地访问Linux命令行,这样可以把所有这些功能和速度都显露出来。我发现自己管理任务时使用CLI的频率远远高于使用GUI。这在很大程度上是因为我更喜欢CLI,但也有许多Linux计算机没有安装任何类型的GUI,甚至那些具备GUI的计算机在试图通过任何远程桌面工具执行远程管理时也非常慢。如果你与远程计算机的Internet连接速度非常快,那么这些远程GUI工具会很有用,但它们永远不会像老式的终端会话一样快,因为GUI数据的网络开销会占用大量带宽。
我并不是说我不使用GUI桌面而且它们“糟糕”。事实上,GUI桌面可以提高我在CLI上的工作效率。我通过同时打开多个终端会话来利用GUI访问CLI,从而使我能够同时访问多个Linux主机上的多个用户的CLI。
我在GUI桌面上使用图形工具。我正在使用LibreOffice Writer—一个功能强大的免费开源图形化文字处理程序来写作本书。我很欣赏并使用CLI和GUI来发挥各自的优势。但是,Linux的真相是CLI为那些愿意使用它的人提供了最强大的功能。
本部分将介绍Linux系统管理员哲学的基础原则。这些原则是Gancarz著作中记载的Unix/Linux哲学原理的发展体现,我们将在这部分中看到更多基础原则。对Unix以及Linux的基本设计的哲学方法有助于实现这两个操作系统的稳定性、优雅性、简单性和强大的功能。
这不是偶然的。Linus Torvalds起初把开发Linux作为业余爱好来做,但故意以Unix为基础来开发它。他接受了免费提供的GNU 实用程序,然后为Linux重新编译它们,并将它们添加到他的操作系统中,当它们组合在一起时,被纯粹主义者称为GNU/Linux。
任何操作系统的个性和可用性都是由设计者所做出的假设决定的。Linux也不例外。它的设计从一开始就像Unix一样,Unix开发人员已经决定Unix允许用户使用融入它的设计中的每一部分功能。不仅如此,他们还为用户提供了使用该功能所需的工具。毕竟,设计出一个操作系统(或者其他任何事情),然后却限制对它的使用没有意义。GNU/Linux是Free Libre开源软件(FLOSS),在其理念和实现方面与Unix非常相似。
由于它们对Linux个性的重要性和广泛影响,我在本书中花费了大量文字来解释这些基础原则,并通过动手实验来说明它们。我相信,只有对这些原则有了坚实的理解,才能理解功能原则,才能更加完全地实现它们对系统管理员的日常任务的适用性。

第3章

数据流
Linux中的所有内容都围绕着数据流(特别是文本流)展开。
我最近使用Google搜索“数据流”,大多数热门内容都涉及处理单个实体(如流媒体视频和音频)中的大量流数据,或由大量个别交易组成的金融机构处理流程。这些都不是我们要在这里讨论的数据流,虽然它们的概念是相同的,并且可以说当前的应用程序正是使用Linux的流处理功能作为处理许多数据类型的模型。
在Unix和Linux世界中,流是指源自某个来源的流文本数据,流可以流动到一个或多个以某种方式对其进行变换的程序,然后它可以存储在文件中或显示在终端会话中。系统管理员的工作与操纵这些数据流的创建和流动密切相关。本章将探讨数据流—它们是什么,如何创建它们,以及它们的一些用法。

3.1 文本流—通用接口

使用标准输入/输出(STDIO)进行程序输入和输出是Linux工作方式的关键基础之一。STDIO最初是为Unix开发的,从那时起它已经进入大多数其他操作系统,包括DOS、Windows和Linux。
这就是Unix的哲学:编写程序,让它只做一件事并且做好。编写程序以协同工作。编写程序来处理文本流,因为这是一个通用接口。
—Doug McIlroy,Unix哲学基础
STDIO由Ken Thompson开发,作为在早期版本的Unix上实现管道所需的基础结构的一部分。实现STDIO的程序使用标准化的文件句柄,而不是存储在磁盘或其他记录介质上的文件来进行输入和输出。STDIO最好被描述为缓冲的数据流,其主要功能是将数据从一个程序、文件或设备的输出,用流的方式传输到另一个程序、文件或设备的输入。

3.2 STDIO文件句柄

STDIO数据流有三种,每种数据流都在那些使用STDIO的程序启动时作为文件自动打开。每种STDIO数据流都与一个文件句柄相关联,文件句柄只是一组描述文件属性的元数据。文件句柄0、1和2按照约定及长期实践分别显式定义为STDIN、STDOUT和STDERR。
STDIN,文件句柄0,是标准输入,通常从键盘输入。STDIN可以从任何文件重定向,包括设备文件而不是键盘。重定向STDIN比STDOUT或STDERR更不常见,但它可以很容易地完成。
STDOUT,文件句柄1,是标准输出,默认情况下将数据流发送到显示器。通常将STDOUT重定向到文件或将其传送到另一个程序以进行进一步处理。
STDERR与文件句柄2相关联,STDERR的数据流通常也会发送到显示器。
如果将STDOUT重定向到文件,则STDERR将继续显示在屏幕上。这确保了当数据流本身没有显示在终端上时,STDERR仍然显示在终端上,从而确保用户可以看到程序执行导致的任何错误。STDERR也可以重定向到相同的文件或传递给管道中的下一个转换器程序。
STDIO实现为C库,可以将stdio.h包含在程序源代码中,以便它可以被编译进生成的可执行文件中。

3.3 生成数据流

大多数核心实用程序(Core Utility)都使用STDIO作为其输出流,而那些生成数据流而不是以某种方式转换数据流的程序,可用于创建我们将用于实验的数据流。数据流可以短至一行甚至一个字符,只要符合需要。
让我们尝试第一个实验并创建一个简短的数据流。

带你读《Linux哲学》之三:数据流

在第4章,我们将这样的STDOUT数据流传输到某些转换器程序的STDIN,以便对流中的数据执行某些操作。目前,我们只是生成数据流。
一些GNU核心实用程序专门用于生成数据流。

带你读《Linux哲学》之三:数据流

你可能会问,“这证明了什么?”这只是说明能用很多方法创建可能有用的数据流。例如,在使用fsck程序修复硬盘驱动器上的问题的过程中,你可能希望对来自此程序的看似无休止的输入请求自动给出“y”响应。该解决方案可以节省大量按下“y”键的操作。

带你读《Linux哲学》之三:数据流

现在,即将介绍的是你绝对不应该尝试的东西。以root身份运行时,rm *命令将删除当前工作目录(pwd)中的每个文件—但它会要求为每个文件输入“y”以验证你确实要删除此文件。这意味着更多按键操作。

带你读《Linux哲学》之三:数据流

3.4 使用“yes”来检验一个理论

使用yes命令的另一个选择是使用包含一些任意且非常无关的数据的文件来填充一个目录,以便填满此目录。我已经使用这种技术来测试当特定目录变满时Linux主机会发生什么情况。我使用这种技术的特定情况是,我正在测试一个理论,因为客户遇到了问题,无法登录到他们的计算机。
我在这一系列实验中都假设U盘在/dev/sdb上,其分区是/dev/sdb1—就像它在我的虚拟机上一样,务必验证此设备已分配在你的计算机上,因为它可能会有所不同。根据你的具体情况使用正确的设备文件。

带你读《Linux哲学》之三:数据流

带你读《Linux哲学》之三:数据流

我在我的一台计算机的/tmp目录中使用了实验3-4中的简单测试,作为我用来确定客户问题的测试的一部分。在/tmp填满之后,用户无法再登录到GUI桌面,但他们仍然可以使用控制台登录。这是因为登录到GUI桌面会在/tmp目录中创建文件,而那里没有剩余空间,因此登录失败。控制台登录不会在/tmp中创建新文件,因此登录成功。我的客户没有尝试登录到控制台,因为他们不熟悉CLI。
在我自己的系统上进行测试验证后,我使用控制台登录客户主机,发现一些大文件占用了/tmp目录中的所有空间。我删除了这些文件并帮助客户确定了产生它们的原因,因此我们能够防止再发生这种事情。

3.5 探索U盘

为了尽可能安全,使用之前准备的U盘进行一些探索。在本实验中,我们将介绍一些文件系统结构。
从简单的dd命令开始。官方称为“磁盘转储”(disk dump),许多系统管理员称它为“磁盘毁灭者”(disk destroyer)是有充分理由的。许多人无意中使用dd命令破坏了整个硬盘驱动器或分区内容。这就是我们将使用U盘执行这些实验的原因。
dd命令是一个功能强大的工具,它允许我们使用任何文件或设备(如硬盘驱动器、磁盘分区、RAM内存、虚拟控制台、终端仿真会话、STDIO等)作为源和目标生成数据流。由于dd命令不会修改这些数据流,因此它允许我们访问原始数据,以便我们可以查看和分析它。
由dd生成的数据流可以用于许多不同的目的,具体详见以下一系列实验。

带你读《Linux哲学》之三:数据流带你读《Linux哲学》之三:数据流

现在在第一个分区的第一个记录上做同样的实验。

带你读《Linux哲学》之三:数据流

我们来看看U盘上还有什么。取决于用于这些实验的U盘的具体情况,可能会有不同的结果。我会告诉你我做了什么,如果有必要,你可以修改它以达到预期的效果。
我们要做的是使用dd命令找到在U盘上创建的文件的目录条目,然后找到一些数据。如果对元数据结构有足够的了解,可以直接解读它们,以在驱动器上找到这些数据的位置,不了解则不得不持续地打印数据,直到找到我们想要的内容为止。
因此,我们可以从所知道的事情开始,然后使用一些技巧来处理。我们知道,在U盘准备期间创建的数据文件位于设备的第一个分区中。因此,我们不需要搜索引导记录和第一个分区之间的空间,其中包含大量空白。至少这是它应该包含的内容。
从/dev/sdb1的开头开始,一次查看几个数据块以找到我们想要的内容。实验3-7中的命令与前一个实验中的命令类似,只是指定的要查看的数据块稍微多一些。如果你的终端不足以同时显示所有数据,则可能必须指定更少的块,或者可以通过less实用程序用管道传输数据并使用它来对数据分页。无论哪种方式都有效。切记,我们以root用户身份执行所有操作,因为非root用户没有所需的权限。

带你读《Linux哲学》之三:数据流

让我们看看dd命令的一个新选项,它给了我们更多的灵活性。

带你读《Linux哲学》之三:数据流

我们在实验3-8中看到分区的第二个10块是空的。它们包含空值,因为它们是空的(没有内容),所以不打印。我们可以继续在分区的开头跳过越来越多的块,或者在count和skip参数中使用更大的增量,例如20和20,但是我希望能节省你一些时间。我发现如果跳过250块,会显示目录条目。如果你的U盘大小不同或格式不同,可能不是这种情况,但它应该是一个好的起点。

带你读《Linux哲学》之三:数据流带你读《Linux哲学》之三:数据流

跳过500个块会显示其中一个文件的数据,如下面的实验3-10所示。

带你读《Linux哲学》之三:数据流带你读《Linux哲学》之三:数据流

一定要花些时间自己探索U盘的内容。你可能会对所发现的东西感到惊讶。

3.6 随机流

事实证明,随机性是计算机中一种理想的东西。系统管理员可能希望生成随机数据流的原因有很多。从其他来源(如硬盘驱动器分区等文件或设备)生成的数据流会包含黑客可用于获取私人或机密数据的非随机数据。使用保证随机的数据流提供了更安全的替代方案。
随机数据流有时可用于覆盖完整分区的内容,例如/dev/sda1,甚至是/dev/sda中的整个硬盘驱动器。
虽然删除文件似乎是永久性的,但事实并非如此。有许多取证工具,经过培训的取证专家可以使用这些工具轻松恢复据称已被删除的文件。恢复已被随机数据覆盖的文件要困难得多。我经常需要删除硬盘驱动器上的所有数据,而且要覆盖它,以便它无法恢复。这样做是为了保护那些把旧计算机“赠送”给我使用以便重复使用或回收的客户和朋友。
无论最终发生在计算机上的是什么,我都会向捐赠计算机的人承诺,我将从硬盘驱动器中清除所有数据。我从计算机中取出驱动器,将它们放入我的插入式硬盘驱动器扩展坞,并使用类似于实验3-11中的命令来覆盖所有数据,而不是像在这个实验中一样仅仅将随机数据倾泻到STDOUT就完事,我将其重定向到需要覆盖的硬盘驱动器的设备文件—但你最好不要这样做。

带你读《Linux哲学》之三:数据流

如果你非常偏执,可以使用shred命令覆盖单个文件以及分区和完整驱动器。它可以根据需要多次写入设备,让你感觉安全,使用随机数据以及专门排序的数据模式进行多次传递,以防止使用哪怕是最敏感的设备从硬盘驱动器恢复任何数据。与使用随机数据的其他实用程序一样,随机流由/dev/urandom设备提供。
随机数据还用作生成随机密码及随机数据和数字的程序的输入种子,以用于科学和统计计算。第4章将更详细地介绍随机性和其他有趣的数据源。

3.7 小结

在本章中,你了解到STDIO只不过是数据流。这些数据几乎可以是任何东西,包括列出目录中的文件命令的输出,或来自特殊设备(如/dev/urandom)的无限数据流,甚至包含来自硬盘驱动器或分区的所有原始数据的流。你学习了一些不同且有趣的方法来生成不同类型的数据流,以及使用dd命令来探索硬盘驱动器的内容。
Linux计算机上的任何设备都可以像数据流一样对待。你可以使用dd和cat等常规工具将数据从设备转储到可以使用其他常规Linux工具处理的STDIO数据流中。
到目前为止,除了查看它们之外,我们还没有对这些数据流做过任何事情。但是等等—还有更多!请继续阅读。

上一篇:带你读《Redis 5设计与源码分析》之二:简单动态字符串


下一篇:2016-4-18 ICMPv6协议[RFC2463]--报文详解