译者:erlinux
探求/dev目录可以让您晓得怎样直接访问到Linux中的设备。
Linux目录结构中有好多有趣的功能,此次我会提到/dev目录一些诱人之处。在继续阅读这篇文章之前,建议你瞧瞧我后面的文章。Linux文件系统[1],一切皆为文件[2],这两篇文章介绍了一些有趣的Linux文件系统概念。请先瞧瞧-我会等你看完再回去。
……
太好了!欢迎回去。如今我们可以继续更详细地阐述/dev目录。
设备文件
设备文件称作为设备特定文件[3]。设备文件拿来为操作系统和用户提供它们代表的设备插口。所有的Linux设备文件均坐落/dev目录下,是根(/)文件系统的一个组成部份,由于这种设备文件在操作系统启动过程中必须可以使用。
关于这种设备文件,要记住的一件重要的事情,就是它们大多不是设备驱动程序。更确切地描述来说,它们是设备驱动程序的门户。数据从应用程序或操作系统传递到设备文件,之后设备文件将它传递给设备驱动程序,驱动程序再将它发给化学设备。反向的数据通道也可以用,从化学设备通过设备驱动程序,再到设备文件,最后抵达应用程序或其他设备。
让我们以一个典型命令的数据流程来直观地瞧瞧。
图1:一个典型命令的简单数据流程。
在前面的图1中,显示一个简单命令的简化数据流程。从一个GUI终端仿真器,比如Konsole或xterm中发出cat/etc/resolv.conf命令,它会从c盘中读取resolv.conf文件,c盘设备驱动程序处理设备的具体功能,比如在硬碟驱动器上定位文件并读取它。数据通过设备文件传递,之后从命令到设备文件,之后到6号伪终端的设备驱动,之后在终端会话中显示。
其实,cat命令的输出可以以下边的形式被重定向到一个文件,cat/etc/resolv.conf>/etc/resolv.bak,这样会创建该文件的备份。在这些情况下,图1右边的数据流量将保持不变,而右侧的数据流量将通过/dev/sda2设备文件、硬盘设备驱动程序,之后到硬碟驱动器本身。
这种设备文件促使使用标准流(STD/IO)和重定向访问Linux或Unix计算机上的任何一个设备十分容易。只需将数据流定向到设备文件,即可将数据发送到该设备。
设备文件类别
设备文件起码可以按两种形式界定。第一种也是最常用的分类是依据与设备相关联的数据流进行界定。例如,tty(teletype)和串行设备被觉得是基于字符的,由于数据流的传送和处理是以一次一个字符或字节进行的;而块类型设备(如硬碟驱动器)是以块为单位传输数据,一般为256个字节的倍数。
您可以在终端上以一个非root用户,改变当前工作目录(PWD)到/dev,并显示长目录列表。这将显示设备文件列表、文件权限及其主、次设备号。诸如,下边的设备文件只是我的Fedora24工作站上/dev目录中的几个文件。它们表示c盘和tty设备类型。注意输出中每行的最左侧的字符。b代表是块类型设备,c代表字符设备。
brw-rw---- 1 root disk 8, 0 Nov 7 07:06 sda
brw-rw---- 1 root disk 8, 1 Nov 7 07:06 sda1
brw-rw---- 1 root disk 8, 16 Nov 7 07:06 sdb
brw-rw---- 1 root disk 8, 17 Nov 7 07:06 sdb1
brw-rw---- 1 root disk 8, 18 Nov 7 07:06 sdb2
crw--w---- 1 root tty 4, 0 Nov 7 07:06 tty0
crw--w---- 1 root tty 4, 1 Nov 7 07:07 tty1
crw--w---- 1 root tty 4, 10 Nov 7 07:06 tty10
crw--w---- 1 root tty 4, 11 Nov 7 07:06 tty11
辨识设备文件更详尽和更明晰的方式是使用设备主要以及次要号。c盘设备主设备号为8,将它们指定为SCSI块设备。请注意,所有PATA和SATA硬碟驱动器都由SCSI子系统管理,由于旧的ATA子系统多年前就因为代码质量糟糕而被觉得不可维护。导致的结果就是,先前被称为“hd[a-z]”的硬碟驱动器如今被称为“sd[a-z]”。
你大约可以从前面的示例中推出c盘驱动器次设备号的模式。次设备号0、16、32等等,直至240,是整个c盘的号。所以主/次8/16表示整个c盘/dev/sdb,8/17是第一个分区的设备文件,/dev/sdb1。数字8/34代表/dev/sdc2。
在里面列表中的tty设备文件编号更简单一些,从tty0到tty63。
上的Linux下的已分配设备[4]文件是设备类型和主次编号分配的即将注册表。它可以帮助您了解所有当前定义的设备的主要/次要号码。
趣味设备文件
让我们花几分钟时间,执行几个有趣的实验,演示Linux设备文件的强悍和灵活性。大多数Linux发行版都有1到7个虚拟控制台,可用于使用shell插口登陆到本地控制台会话。可以使用Ctrl-Alt-F1(控制台1),Ctrl-Alt-F2(控制台2)等按键组合键来访问。
请按Ctrl-Alt-F2切换到控制台2。在个别发行版linux删除设备,登陆显示的信息包括了与此控制台关联的tty设备,但大多不包括。它应当是tty2,由于你是在控制台2中。
以非root用户身分登入。之后你可以使用whoami命令—是的,就是这个命令,带空格—来确定那个tty设备联接到这个控制台。
在我们实际执行此实验之前,瞧瞧/dev中的tty2和tty3的设备列表。
ls -l /dev/tty[23]
有大量的tty设备,但我们不关心她们中的大多数,只注意tty2和tty3设备。作为设备文件,它们没哪些非常之处。它们都只是字符类型设备。我们将使用这种设备进行此实验。tty2设备联接到虚拟控制台2,tty3设备联接到虚拟控制台3。
按Ctrl-Alt-F3切换到控制台3。再度以同一非root用户身分登入。现今在控制台3上输入以下命令。
echo "Hello world" > /dev/tty2
按Ctrl-Alt-f2键以返回到控制台2。字符串“Helloworld”(没有冒号)将显示在控制台2。
该实验也可以使用GUI桌面上的终端仿真器来执行。桌面上的终端会话使用/dev中的伪终端设备,如/dev/pts/1。使用Konsole或Xterm打开两个终端会话。确定它们联接到什么伪终端,并使用一个向另一个发送消息。
如今继续实验,使用cat命令,试试在不同的终端上显示/etc/fstab文件。
另一个有趣的实验是使用cat命令将文件直接复印到复印机。假定您的复印机设备是/dev/usb/lp0,但是您的复印机可以直接复印PDF文件,以下命令将在您的复印机上复印test.pdf文件。
cat test.pdf > /dev/usb/lp0
/dev目录包含一些特别有趣的设备文件linux就该这么学,这种文件是硬件的入口,人们一般不觉得这是硬碟驱动器或显示器之类的设备。诸如,系统储存器RAM不是一般被觉得是“设备”的东西,而/dev/mem是通过其可以实现对储存器的直接访问的入口。下边的反例有一些有趣的结果。
dd if=/dev/mem bs=2048 count=100
里面的dd命令提供比简单地使用cat命令dump所有系统的显存提供了更多的控制。它提供了指定从/dev/mem读取多少数据的能力,还容许指定从储存器那里开始读取数据。其实读取了一些显存,但内核响应了以下错误,在/var/log/messages中可以见到。
Nov 14 14:37:31 david kernel: usercopy: kernel memory exposure attempt detected from ffff9f78c0010000 (dma-kmalloc-512) (2048 bytes)
这个错误意味着内核正在通过保护属于其他进程的显存来完成它的工作,这正是它应当工作的方法。所以,尽管可以使用/dev/mem来显示储存在RAM显存中的数据,并且访问的大多数显存空间是受保护的而且会造成错误。只可以访问由内核显存管理器分配给运行dd命令的BASHshell的虚拟显存,而不会造成错误。抱歉,但你不能窥探不属于你的显存,除非你发觉了一个可借助的漏洞。
/dev中还有一些特别有趣的设备文件。设备文件,zero,random和urandom不与任何化学设备相关联。
比如,空设备/dev/可以用作来自shell命令或程序的输出重定向的目标,便于它们不显示在终端上。我时常在我的BASH脚本中使用这个,以避免向用户展示可能会让她们倍感困扰的输出。/dev/设备可用于形成一个空字符串。使用如下所示的dd命令查看/dev/设备文件的一些输出。
# dd if=/dev/ bs=512 count=500 | od -c
0+0 records in
0+0 records out
0 bytes copied, 1.5885e-05 s, 0.0 kB/s
0000000
注意,由于空字符哪些也没有所以确实没有可见的输出。注意瞧瞧字节数。
/dev/random和/dev/urandom设备也很有趣。正如它们的名子所暗示的,它们都形成随机输出,不仅仅是数字,而是任何字节组合。/dev/urandom设备形成的是确定性的随机输出,而且十分快。这意味着输出由算法确定,并使用种子字符串作为起点。结果,假若原始种子是已知的,则黑客可以重现输出,虽然十分困难,但这是有可能的。使用命令cat/dev/urandom可以查看典型的输出,使用Ctrl-c退出。
/dev/random设备文件生成非确定性的随机输出,但它形成的输出更慢一些。该输出不是由依赖于以前数字的算法确定的,而是由击键动作和键盘联通而形成的。这些技巧促使复制特定系列的随机数要困难得多。使用cat命令去查看一些来自/dev/random设备文件输出。尝试联通键盘以查看它怎样影响输出。
正如其名子所暗示的,/dev/zero设备文件形成一个无止境的零作为输出。注意,这种是八补码零,而不是ASCII字符零(0)。使用如下所示的dd查看/dev/zero设备文件中的一些输出
# dd if=/dev/zero bs=512 count=500 | od -c
0000000
*
500+0 records in
500+0 records out
256000 bytes (256 kB, 250 KiB) copied, 0.00126996 s, 202 MB/s
0764000
请注意,此命令的字节数不为零。
创建设备文件
在过去,在/dev中的设备文件都是在安装时创建的,致使一个目录中有几乎所有的设备文件,虽然大多数文件永远不会用到。在不常发生的情况,比如须要新的设备文件,或意外删掉后须要重新创建设备文件,可以使用mknod程序自动创建设备文件。前提是你必须晓得设备的主要和次要号码。
CentOS和RHEL6、7,以及Fedora的所有版本——可以溯源到起码Fedora15,使用较新的创建设备文件的方式。所有设备文件都是在引导时创建的。这是由于udev设备管理器在设备添加和删掉发生时会进行检查。这可实现在主机启动和运行时的真正的动态即插即用功能。它还在引导时执行相同的任务,通过在引导过程的很早的时期检查系统上安装的所有设备。[5]上有一篇很棒的对udev的描述[6]。
回到/dev中的文件列表,注意文件的日期和时间。所有文件都是在先前启动时创建的。您可以使用uptime或则last命令来验证这一点。在里面我的设备列表中,所有那些文件都是在11月7日下午7:06创建的,这是我最后一次启动系统。
其实,mknod命令始终可用,但新的MAKEDEV(是的,所有字母小写,在我看来是违反Linux使用大写命令名的原则的)命令提供了一个创建设备文件的更容易的界面。在当前版本的Fedora或CentOS7中,默认情况下不安装MAKEDEV命令;它安装在CentOS6。您可以使用YUM或DNF来安装MAKEDEV包。
推论
有趣的是,我好久没有创建一个设备文件的须要了。但是,近来我遇见一个有趣的情况,其中一个我常使用的设备文件没有创建,我不得不创建它。以后该设备再没出过问题。所以遗失设备文件的情况依然可以发生linux防火墙设置,晓得怎样处理它可能很重要。
设备文件有无数种,您遇见的设备文件我可能没有囊括到。这种信息在所下边引用的资源中有大量的细节信息可用。关于那些文件的功能和工具linux删除设备,我希望我早已给您一些基本的了解,下一步您自己可以探求更多。
资源
作者:DavidBoth[12]译者:erlinux[13]校对:jasminepeng
本文由LCTT[14]组织编译,Linux中国荣誉推出