linux 命令行 导数据
作者注释:本文的大部分内容均摘录,并进行了一些重要的编辑以适合Opensource.com文章格式,摘自新书《 SysAdmins的Linux哲学》的第3章:数据流。
Linux中的所有内容都围绕数据流,尤其是文本流。 数据流是GNU实用程序 ,Linux核心实用程序和许多其他命令行工具用来执行其工作的原材料。
顾名思义,数据流是使用STDIO从一个文件,设备或程序传递到另一文件,设备或程序的数据流,尤其是文本数据。 本章介绍了使用管道使用STDIO将数据流从一个实用程序连接到另一个实用程序的方法。 您将了解到,这些程序的功能是以某种方式转换数据。 您还将了解如何使用重定向将数据重定向到文件。
标准术语“过滤器”表示我不同意的内容。 根据定义,过滤器是一种去除某些东西的装置或工具,例如空气过滤器可以去除空气中的污染物,从而使您的汽车内燃发动机不会因这些颗粒而磨死。 在我的高中和大学化学课中,滤纸用于去除液体中的颗粒。 我的家用HVAC系统中的空气过滤器去除了我不想呼吸的微粒。
尽管它们有时确实会从流中过滤掉不需要的数据,但我更喜欢术语“变压器”,因为这些实用程序能做的更多。 他们可以将数据添加到流中,以某些令人惊奇的方式修改数据,对其进行排序,重新排列每一行中的数据,并根据数据流的内容执行操作等等。 随意使用您喜欢的任何术语,但我更喜欢变压器。 我希望我独自一人。
可以通过使用管道将转换器插入流中来操纵数据流。 sysadmin使用每个转换器程序对流中的数据执行某些操作,从而以某种方式更改其内容。 然后,可以在管道的末尾使用重定向来将数据流定向到文件。 如前所述,该文件可以是硬盘驱动器上的实际数据文件,也可以是设备文件,例如驱动器分区,打印机,终端,伪终端或连接到计算机的任何其他设备。
使用这些小型但功能强大的转换器程序操纵这些数据流的能力对于Linux命令行界面的功能至关重要。 许多核心实用程序是转换器程序,并使用STDIO。
在Unix和Linux世界中,流是源自某些源的文本数据流。 流可以流到以某种方式对其进行转换的一个或多个程序,然后可以将其存储在文件中或显示在终端会话中。 作为系统管理员,您的工作与操纵这些数据流的创建和流密切相关。 在本文中,我们将探讨数据流,它们是什么,如何创建它们,以及有关如何使用它们的一些知识。
将标准输入/输出(STDIO)用于程序输入和输出是Linux处事方式的关键基础。 STDIO最初是为Unix开发的,此后便进入了其他大多数操作系统,包括DOS,Windows和Linux。
“ 这是Unix的哲学:编写能做一件事并且做得很好的程序。 编写程序以协同工作。 编写程序来处理文本流,因为这是一个通用接口。”
— Doug McIlroy,《 Unix哲学基础》
STDIO由Ken Thompson开发,是在早期版本的Unix上实现管道所需的基础结构的一部分。 实现STDIO的程序使用标准化的文件句柄进行输入和输出,而不是使用存储在磁盘或其他记录介质上的文件。 最好将STDIO描述为缓冲的数据流,其主要功能是将数据从一个程序,文件或设备的输出流式传输到另一个程序,文件或设备的输入。
一共有三个STDIO数据流,每个数据流在程序启动时都会作为文件自动打开-那些使用STDIO的程序。 每个STDIO数据流都与一个文件句柄相关联,该文件句柄只是描述文件属性的一组元数据。 文件句柄0、1和2分别由惯例和长期惯例明确定义为STDIN,STDOUT和STDERR。
STDIN,文件句柄0 ,是标准输入,通常是从键盘输入的。 可以从任何文件(包括设备文件)而不是键盘重定向STDIN。 重定向STDIN并不常见,但是可以做到。
STDOUT(文件句柄1 )是标准输出,默认情况下会将数据流发送到显示器。 通常将STDOUT重定向到文件或将其通过管道传输到另一个程序进行进一步处理。
STDERR,文件句柄2 。 STDERR的数据流通常也发送到显示器。
如果将STDOUT重定向到文件,则STDERR继续显示在屏幕上。 这样可以确保当数据流本身未显示在终端上时,即显示STDERR,从而确保用户将看到由程序执行引起的任何错误。 也可以将STDERR重定向到相同的目录,或传递到管道中的下一个转换器程序。
STDIO被实现为C库stdio.h ,可以将其包含在程序的源代码中,以便可以将其编译为最终的可执行文件。
您可以在Linux主机的/ tmp目录中安全地执行以下实验。 以root用户身份将/ tmp设置为PWD,创建一个测试目录,然后将新目录设置为PWD。
# cd /tmp ; mkdir test ; cd test
输入并运行以下命令行程序,以在驱动器上创建一些包含内容的文件。 我们仅使用dmesg
命令为要包含的文件提供数据。 内容并不重要,只是每个文件都包含一些内容。
# for I in 0 1 2 3 4 5 6 7 8 9 ; do dmesg > file$I.txt ; done
验证/ tmp /中现在至少有10个文件,名称为file0.txt到file9.txt 。
# ll
total 1320
-rw-r--r-- 1 root root 131402 Oct 17 15:50 file0.txt
-rw-r--r-- 1 root root 131402 Oct 17 15:50 file1.txt
-rw-r--r-- 1 root root 131402 Oct 17 15:50 file2.txt
-rw-r--r-- 1 root root 131402 Oct 17 15:50 file3.txt
-rw-r--r-- 1 root root 131402 Oct 17 15:50 file4.txt
-rw-r--r-- 1 root root 131402 Oct 17 15:50 file5.txt
-rw-r--r-- 1 root root 131402 Oct 17 15:50 file6.txt
-rw-r--r-- 1 root root 131402 Oct 17 15:50 file7.txt
-rw-r--r-- 1 root root 131402 Oct 17 15:50 file8.txt
-rw-r--r-- 1 root root 131402 Oct 17 15:50 file9.txt
我们已经使用dmesg
命令生成了数据流,该命令已重定向到一系列文件。 大多数核心实用程序都将STDIO用作其输出流,而那些生成数据流的工具(而不是以某种方式转换数据流)可以用来创建我们将用于实验的数据流。 数据流可以短至一行,甚至可以是单个字符,并且可以根据需要而定。
现在该进行一些探索了。 在本实验中,我们将研究一些文件系统结构。
让我们从简单的事情开始。 您至少应该对dd
命令有所了解。 正式被称为“磁盘转储”,许多系统管理员有充分的理由将其称为“磁盘破坏者”。 我们中许多人无意间使用dd
命令破坏了整个硬盘或分区的内容。 这就是为什么我们将在/ tmp / test目录中闲逛以执行其中一些实验的原因。
尽管享有盛誉,但dd
在探索各种类型的存储介质,硬盘驱动器和分区方面还是非常有用的。 我们还将把它用作探索Linux其他方面的工具。
如果尚未登录,请以root用户身份登录到终端会话。 我们首先需要使用lsblk
命令确定硬盘驱动器的设备专用文件。
[root@studentvm1 test]# lsblk -i
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 60G 0 disk
|-sda1 8:1 0 1G 0 part /boot
`-sda2 8:2 0 59G 0 part
|-fedora_studentvm1-pool00_tmeta 253:0 0 4M 0 lvm
| `-fedora_studentvm1-pool00-tpool 253:2 0 2G 0 lvm
| |-fedora_studentvm1-root 253:3 0 2G 0 lvm /
| `-fedora_studentvm1-pool00 253:6 0 2G 0 lvm
|-fedora_studentvm1-pool00_tdata 253:1 0 2G 0 lvm
| `-fedora_studentvm1-pool00-tpool 253:2 0 2G 0 lvm
| |-fedora_studentvm1-root 253:3 0 2G 0 lvm /
| `-fedora_studentvm1-pool00 253:6 0 2G 0 lvm
|-fedora_studentvm1-swap 253:4 0 10G 0 lvm [SWAP]
|-fedora_studentvm1-usr 253:5 0 15G 0 lvm /usr
|-fedora_studentvm1-home 253:7 0 2G 0 lvm /home
|-fedora_studentvm1-var 253:8 0 10G 0 lvm /var
`-fedora_studentvm1-tmp 253:9 0 5G 0 lvm /tmp
sr0 11:0 1 1024M 0 rom
由此可见,该主机上只有一个硬盘驱动器,与之关联的设备专用文件是/ dev / sda ,并且具有两个分区。 / dev / sda1分区是引导分区, / dev / sda2分区包含一个卷组,在该卷组上已创建了主机的其余逻辑卷。
在终端会话中以root用户身份使用dd
命令查看硬盘驱动器的启动记录(假设已将其分配给/ dev / sda设备)。 您可能不会想到bs=
参数。 它仅指定块大小,而count=
参数指定要转储到STDIO的块数。 if=
参数指定数据流的源,在这种情况下为/ dev / sda设备。 注意,我们不是在看分区的第一块,而是在看硬盘驱动器的第一块。
[root@studentvm1 test]# dd if=/dev/sda bs=512 count=1
c # м ؎ | # # !# 8#u
# u # # # | t# L# # | # ??t pt# y|1 ؎м d|< t# R |1 D#@ D D# ##f #\|f f #`|f \
D#p B #r p # K`# # 1 #a` #f u# f1 f TCPAf #f #a &Z| #} # .} 4 3} . # GRUB GeomHard DiskRead Error
# #
1+0 records out
512 bytes copied, 4.3856e-05 s, 11.7 MB/s
这将打印引导记录的文本,它是磁盘上的第一个块(任何磁盘)。 在这种情况下,存在有关文件系统的信息,尽管它由于以二进制格式存储而不可读,但存在分区表的信息。 如果这是可引导设备,则GRUB的第1阶段或其他引导加载程序将位于此扇区中。 最后三行包含有关记录数和已处理字节的数据。
从/ dev / sda1的开头开始,让我们一次查看几个数据块以查找所需的内容。 该命令与上一个命令相似,不同之处在于,我们还指定了一些要查看的数据块。 如果终端的大小不足以一次显示所有数据,则可能必须指定较少的块,或者可以通过less实用程序通过管道传输数据并将其用于分页数据,无论哪种方法都可以。 请记住,我们以root用户身份执行所有这些操作,因为非root用户没有所需的权限。
输入与上一个实验相同的命令,但是将要显示的块数增加到100,如下所示,以便显示更多数据。
[root@studentvm1 test]# dd if=/dev/sda1 bs=512 count=100
##33 #: ## :o [:o [# S ### q[#
#< #{5OZh GJ͞#t Ұ##boot/bootysimage/booC dp G' *) #A ##@
# q[
## ## ### # To=###<#8 #'# ### # # ' #Xi # ` qT
<
r ] # # ## ## ## # ## ## ## # ## ## # # # ## # ## ## # # # # # # #
#
#
#
#
#
#
#
#
#100+0 records in
100+0 records out
51200 bytes (51 kB, 50 KiB) copied, 0.00117615 s, 43.5 MB/s
现在尝试此命令。 我不会在这里复制整个数据流,因为它将占用大量空间。 使用Ctrl-C中断并停止数据流。
[root@studentvm1 test]# dd if=/dev/sda
此命令产生的数据流是硬盘驱动器/ dev / sda的完整内容,包括引导记录,分区表以及所有分区及其内容。 可以将这些数据重定向到文件中,以用作可以执行裸机恢复的完整备份。 也可以将其直接发送到另一个硬盘以克隆第一个硬盘。 但请勿执行此特定实验。
[root@studentvm1 test]# dd if=/dev/sda of=/dev/sdx
您可以看到dd
命令对于探索各种类型的文件系统的结构,在有缺陷的存储设备上定位数据等等非常有用。 它还会产生一个数据流,我们可以在其中使用Transformer Utility进行修改或查看。
真正的要点是dd
与许多Linux命令一样,会产生数据流作为其输出。 可以使用其他工具以多种方式搜索和操纵该数据流。 它甚至可以用于类似虚影的备份或磁盘复制。
事实证明,随机性在计算机中是可取的,谁知道呢? 系统管理员可能出于多种原因想要生成随机数据流。 有时,随机数据流对于覆盖/ dev / sda等完整分区(例如/ dev / sda1 )甚至整个硬盘的内容很有用。
以非root用户身份执行此实验。 输入此命令以将无休止的随机数据流打印到STDIO。
[student@studentvm1 ~]$ cat /dev/urandom
使用Ctrl-C中断并停止数据流。 您可能需要多次使用Ctrl-C 。
随机数据还用作程序的输入种子,这些程序生成随机密码以及随机数据和数字以用于科学和统计计算。 我将在第24章:一切都是文件,对随机性和其他有趣的数据源进行更详细的介绍。
管道对于我们在命令行上完成令人惊奇的事情的能力至关重要,因此,我认为认识到它们是Unix早期由道格拉斯·麦克罗伊(Douglas McIlroy)发明的(感谢Doug!)非常重要。 普林斯顿大学的网站上有一段采访麦克罗伊的片段,其中他讨论了管道的创建以及Unix哲学的起源。
请注意,接下来显示的简单命令行程序中使用了管道,该管道列出了每个已登录用户的时间,无论该用户进行了多少次登录。 以学生用户身份执行此实验。 输入如下所示的命令:
[student@studentvm1 ~]$ w | tail -n +3 | awk '{print $1}' | sort | uniq
root
student
[student@studentvm1 ~]$
该命令的结果产生两行数据,表明用户的root和Student均已登录。它没有显示每个用户登录的次数。您的结果几乎肯定与我的不同。
竖线(|)代表的管道是将这些命令行实用程序连接在一起的语法胶水,即运算符。 管道允许“管道传输”来自一个命令的标准输出,即从一个命令的“标准输出”流到下一个命令的“标准输入”。
|&运算符可用于将STDERR和STDOUT传递到下一条命令的STDIN。 这并非总是可取的,但是它确实提供了记录STDERR数据流以解决问题的灵活性。
与管道连接的一系列程序称为管道,而使用STDIO的程序正式称为过滤器,但我更喜欢术语“变压器”。
考虑一下如果我们无法通过管道将数据流从一个命令传递到下一个命令,该程序将如何工作。 第一个命令将对数据执行其任务,然后该命令的输出将需要保存在文件中。 下一条命令将必须从中间文件读取数据流并对其进行修改,然后将其自身的输出发送到新的临时数据文件中。 第三条命令必须从第二个临时数据文件中获取其数据,并对数据流执行自己的操作,然后将结果数据流存储在另一个临时文件中。 在每个步骤中,都必须以某种方式将数据文件名从一个命令传送到下一个命令。
我什至不能忍受考虑,因为它是如此复杂。 切记:朴实无华!
当我在做新的事情,解决一个新问题时,我通常不只是从头开始输入一个完整的Bash命令管道。 我通常只从管道中的一个或两个命令开始,然后通过添加更多命令以进一步处理数据流从那里开始构建。 这使我可以查看管道中每个命令之后的数据流状态,并根据需要进行更正。
可以建立非常复杂的管道,从而可以使用许多与STDIO一起使用的实用程序来转换数据流。
重定向是将程序的STDOUT数据流重定向到文件而不是显示器的默认目标的功能。 “大于”(>)字符,又称“ gt”,是STDOUT重定向的语法符号。
重定向命令的STDOUT可用于创建包含该命令结果的文件。
[student@studentvm1 ~]$ df -h > diskusage.txt
除非有错误,否则此命令不会输出到终端。 这是因为STDOUT数据流被重定向到文件,而STDERR仍被定向到STDOUT设备(即显示设备)。 您可以使用以下命令查看刚刚创建的文件的内容:
[student@studentvm1 test]# cat diskusage.txt
Filesystem Size Used Avail Use% Mounted on
devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 0 2.0G 0% /dev/shm
tmpfs 2.0G 1.2M 2.0G 1% /run
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/mapper/fedora_studentvm1-root 2.0G 50M 1.8G 3% /
/dev/mapper/fedora_studentvm1-usr 15G 4.5G 9.5G 33% /usr
/dev/mapper/fedora_studentvm1-var 9.8G 1.1G 8.2G 12% /var
/dev/mapper/fedora_studentvm1-tmp 4.9G 21M 4.6G 1% /tmp
/dev/mapper/fedora_studentvm1-home 2.0G 7.2M 1.8G 1% /home
/dev/sda1 976M 221M 689M 25% /boot
tmpfs 395M 0 395M 0% /run/user/0
tmpfs 395M 12K 395M 1% /run/user/1000
使用>符号重定向数据流时,如果指定的文件尚不存在,则会创建该文件。 如果确实存在,则内容将被命令中的数据流覆盖。 您可以使用双大于号>>将新的数据流附加到文件中的任何现有内容。
[student@studentvm1 ~]$ df -h >> diskusage.txt
您可以使用cat
和/或less
cat
来查看diskusage.txt文件,以验证新数据是否已附加到文件末尾。
<(小于)符号将数据重定向到程序的STDIN。 您可能想使用此方法将文件中的数据从不输入文件名作为参数但使用STDIN的命令输入到STDIN。 尽管输入源可以重定向到STDIN,例如用作grep输入的文件,但是通常没有必要,因为grep还将文件名作为参数来指定输入源。 大多数其他命令还将文件名作为其输入源的参数。
grep
命令用于从数据流中选择与指定模式匹配的行。 grep
是最常用的变压器实用程序之一,可以以一些非常有创意和有趣的方式使用。 grep
命令是少数可以正确称为过滤器的命令之一,因为它确实过滤掉了不需要的数据流的所有行。 它仅将所需的行保留在剩余数据流中。
如果PWD不是/ tmp / test目录,请添加它。 首先,我们创建一个随机数据流以存储在文件中。 在这种情况下,我们希望将随机数据限制在可打印字符的范围内。 一个好的密码生成器程序可以做到这一点。 以下程序(如果尚未安装pwgen
则可能需要安装)创建一个包含50,000个密码的文件,每个可打印字符的长度为80个字符。 尝试不先将其重定向到random.txt文件,首先查看其外观,然后在将输出数据流重定向到该文件后再进行操作。
$ pwgen -sy 80 50000 > random.txt
考虑到密码太多,它们中的某些字符串很可能是相同的。 首先, cat
的random.txt文件,然后使用grep
命令来查找一些总之,从屏幕上的最后十个密码随机选择的字符串。 我在这十个密码之一中看到了“看见”一词,因此我的命令如下所示: grep see random.txt
,您可以尝试尝试,但是您还应该选择一些自己的字符串来检查。 两到四个字符的短字符串效果最好。
$ grep see random.txt
R=p)'s/~0}wr~2(OqaL.S7DNyxlmO69`"12u]h@rp[D2%3}1b87+>Vk,;4a0hX]d7see;1%9|wMp6Yl.
bSM_mt_hPy|YZ1NU@[;zV2-see)>(BSK~n5mmb9~h)yx{a&$_e
cjR1QWZwEgl48[3i-(^x9D=v)seeYT2R#M:>wDh?Tn$]HZU7}j!7bIiIr^cI.DI)W0D"'[email protected]
z=tXcjVv^G\nW`,y=bED]d|7%s6iYT^a^Bvsee:v\UmWT02|P|nq%A*;+Ng[$S%*s)-ls"dUfo|0P5+n
管道和重定向的使用允许在Linux命令行上使用数据流执行许多惊人而强大的任务。 它是将STDIO数据流从一个程序或文件传输到另一个程序或文件的管道。 通过一个或多个转换器程序通过管道传输数据流的功能支持对这些流中的数据进行强大而灵活的操作。
实验中演示的管道中的每个程序都很小,并且每个程序都做得很好。 它们也是变压器。 也就是说,他们采用标准输入,以某种方式对其进行处理,然后将结果发送到标准输出。 将这些程序实现为将其处理后的数据流从其自己的标准输出发送到其他程序的标准输入的转换器是对管道作为Linux工具实施的补充,并且是必需的。
STDIO就是数据流。 这些数据几乎可以是任何命令的输出,这些命令可以列出目录中的文件,也可以是来自诸如/ dev / urandom之类的特殊设备的不间断数据流,甚至还可以是包含来自硬盘的所有原始数据的流。驱动器或分区。
Linux计算机上的任何设备都可以视为数据流。 您可以使用dd
和cat
等普通工具将数据从设备转储到STDIO数据流中,可以使用其他普通Linux工具对其进行处理。
翻译自: https://opensource.com/article/18/10/linux-data-streams
linux 命令行 导数据