Featured image of post Linux中虚拟设备的用途和区别

Linux中虚拟设备的用途和区别

介绍Linux中的四个虚拟设备/dev/null、/dev/zero、/dev/random和/dev/urandom,它们的用途和区别,以及如何通过一些命令来操作它们。结合实例和代码,讲解了这些设备的原理和功能,对于想要了解Linux系统的读者有一定的参考价值。

Linux系统中有一些特殊的虚拟设备,它们不对应任何真实的硬件,但是可以像普通的文件一样进行读写操作。这些虚拟设备有各自的用途和特点,本文将介绍其中四种常见的虚拟设备:/dev/null/dev/zero/dev/random/dev/urandom

/dev/null

/dev/null是一个空设备,也称为黑洞设备。它可以接受任何输入,但是不产生任何输出。当我们想要忽略某个命令或程序的输出时,可以将其重定向到/dev/null。例如:

1
2
$ ls -l /dev/null
crw-rw-rw- 1 root root 1, 3 Jun  7 06:43 /dev/null
1
$ echo "Hello world" > /dev/null
1
$ cat /dev/null

上面的例子中,我们可以看到/dev/null是一个字符设备,它的权限是666,也就是任何用户都可以读写它。我们将一个字符串输出到/dev/null后,没有任何反馈。我们也不能从/dev/null中读取任何内容。

/dev/zero

/dev/zero是一个零设备,它可以产生无限多个字节的0。当我们想要创建一个指定大小的空文件时,可以使用/dev/zero。例如:

1
2
$ ls -l /dev/zero
crw-rw-rw- 1 root root 1, 5 Jun  7 06:43 /dev/zero
1
2
3
4
$ dd if=/dev/zero of=test.txt bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB, 10 MiB) copied, 0.00759017 s, 1.4 GB/s
1
2
$ ls -l test.txt
-rw-r--r-- 1 user user 10485760 Jun  7 06:44 test.txt

上面的例子中,我们可以看到/dev/zero是一个字符设备,它的权限也是666。我们使用dd命令从/dev/zero中读取了10MB的0,并写入到test.txt文件中。我们可以看到test.txt文件的大小确实是10MB。

/dev/random和/dev/urandom

/dev/random/dev/urandom是两个随机数设备,它们可以产生伪随机数。这些随机数是根据系统的熵池生成的,熵池是系统收集的一些随机事件,如键盘输入、鼠标移动、网络流量等。当我们想要生成一些随机数据时,可以使用这两个设备。例如:

1
2
3
$ ls -l /dev/random /dev/urandom
crw-rw-rw- 1 root root 1, 8 Jun  7 06:43 /dev/random
crw-rw-rw- 1 root root 1, 9 Jun  7 06:43 /dev/urandom
1
2
3
$ head -c 16 /dev/random | hexdump -C
00000000  97 f3 b6 32 4a c7 8a 7d  84 42 fc 1f 1e f4 33 e3  |...2J..}.B....3.|
00000010
1
2
3
$ head -c 16 /dev/urandom | hexdump -C
00000000  b8 ca 5d 19 4b d0 7a c1  42 e8 dc f0 a1 c1 6d 7d  |..].K.z.B.....m}|
00000010

上面的例子中,我们可以看到/dev/random/dev/urandom都是字符设备,它们的权限也都是666。我们使用head命令从这两个设备中读取了16个字节的随机数据,并用hexdump命令显示出来。

那么,这两个设备有什么区别呢?简单来说,/dev/random是一个阻塞设备,它会在熵池不足时停止输出,直到有足够的随机事件发生。这样可以保证随机数的质量,但是也会导致读取速度很慢。/dev/urandom是一个非阻塞设备,它会在熵池不足时使用伪随机数生成算法来补充输出,这样可以保证读取速度很快,但是也会降低随机数的质量。因此,一般来说,如果我们需要高质量的随机数,比如用于加密或安全相关的场景,我们应该使用/dev/random。如果我们只需要低质量的随机数,比如用于测试或娱乐相关的场景,我们可以使用/dev/urandom

下面这个例子,利用 /dev/urandom 设备产生一个 128 位的随机字符串:

1
2
3
$ str=$(cat /dev/urandom | hexdump | tr -d ' ' | head -n 1)
$ echo ${str:7}
17539187d2e8b8e26d49bec90465c14d

总结

本文介绍了Linux中的四种常见的虚拟设备:/dev/null/dev/zero/dev/random/dev/urandom。它们都可以像普通的文件一样进行读写操作,但是有各自的用途和特点。我们可以根据不同的需求选择合适的虚拟设备来完成一些特殊的任务。

本文参考资料:

扩展阅读

字符设备

字符设备是一种在Linux中与设备通信的方式,它通过发送和接收单个字符(字节)来与设备交互。字符设备不对应任何真实的硬件,而是通过设备文件来表示。设备文件是一种特殊的文件,它位于/dev目录下,可以像普通文件一样进行读写操作,但是实际上是由内核转发给相应的设备驱动程序。字符设备的一个例子是串口,它可以一次传输一个字节的数据。

字符设备与另一种类型的设备驱动程序——块设备不同。块设备是一种以数据块为单位进行传输的设备,例如硬盘、USB摄像头等。块设备通常需要经过文件系统和缓冲区管理的处理,而字符设备则不需要。

要创建一个字符设备,需要指定一个主设备号和一个次设备号。主设备号用于标识设备类型或驱动程序,次设备号用于标识具体的物理设备或逻辑分区。例如,/dev/ttyS0是一个字符设备,它的主设备号是4,次设备号是64,表示它是第一个串口。

要编写一个字符设备驱动程序,需要实现一些基本的函数,如打开、关闭、读、写、控制等,并将它们注册到内核中。这样,当用户对字符设备文件进行操作时,就会调用相应的驱动函数。

字符设备参考资料:

hexdump

hexdump是一个Linux命令,它可以将二进制文件的内容以十六进制、十进制、八进制或ASCII码的形式显示出来。它是一个用于检查文件的工具,可以用于数据恢复、逆向工程和编程。

例如,如果你想要查看一个程序的可执行代码,你可以使用hexdump来实现。

使用hexdump命令时,可以指定不同的选项来控制输出的格式和内容。例如,-C选项可以显示每个字节对应的ASCII字符,-v选项可以显示所有的数据而不省略重复的部分,-n选项可以限制输出的字节数等。

hexdump命令的一般语法是:

1
hexdump [options] [file …]

如果没有指定文件名,hexdump会从标准输入读取数据。

hexdump -C命令的输出格式是:

1
address hex1 hex2 … hex8 ascii

address是文件中的偏移量,hex1到hex8是每两个字节组成的十六进制数,ascii是对应的ASCII字符。如果某个字节不是可打印的ASCII字符,就用.代替。

hexdump参考资料: