第27章. /dev 和 /proc

Linux 或 UNIX 机器都带有/dev/proc目录用于特殊目的.

27.1. /dev

/dev 目录内包含以或不以硬件形式出现的物理设备条目. [1] 包含被挂载的文件系统的硬设备分区在/dev目录下都有对应的条目, 就像df命令所展示的.
 bash$ df
 Filesystem           1k-blocks      Used Available Use%
 Mounted on
 /dev/hda6               495876    222748    247527  48% /
 /dev/hda1                50755      3887     44248   9% /boot
 /dev/hda8               367013     13262    334803   4% /home
 /dev/hda5              1714416   1123624    503704  70% /usr
 	      

在其他方面, /dev 目录也包含环回设备(loopback devices) , 例如/dev/loop0. 环回设备是一个使普通文件能被像对待块设备一样来进行存取的机制. [2] 这使我们可以将一个大文件内的整个文件系统挂载到系统目录下. 参考例子 13-8例子 13-7.

/dev还有少量的伪设备用于特殊的用途, 例如/dev/null, /dev/zero, /dev/urandom, /dev/sda1, /dev/udp, 和/dev/tcp.

例如:

为了挂载(mount) 一个USB闪盘设备, 将下面一行添加到/etc/fstab. [3]
   1 /dev/sda1    /mnt/flashdrive    auto    noauto,user,noatime    0 0
(也请参考例子 A-23.)

当对/dev/tcp/$host/$port 伪设备文件执行一个命令时, Bash会打开一个相关的TCP的socket. [4]

nist.gov得到时间:

 bash$ cat </dev/tcp/time.nist.gov/13
 53082 04-03-18 04:26:54 68 0 0 502.3 UTC(NIST) *
 	      

[Mark贡献了上面的例子.]

下载一个 URL:

 bash$ exec 5<>/dev/tcp/www.net.cn/80
 bash$ echo -e "GET / HTTP/1.0\n" >&5
 bash$ cat <&5
 	      

[Thanks, Mark 和 Mihai Maties.]


例子 27-1. 利用/dev/tcp 来检修故障

   1 #!/bin/bash
   2 # dev-tcp.sh: 用/dev/tcp 重定向来检查Internet连接.
   3 
   4 # Troy Engel编写.
   5 # 已得到作者允许.
   6  
   7 TCP_HOST=www.dns-diy.com   # 一个已知的 ISP.
   8 TCP_PORT=80                # http的端口是80 .
   9   
  10 # 尝试连接. (有些像 'ping' . . .) 
  11 echo "HEAD / HTTP/1.0" >/dev/tcp/${TCP_HOST}/${TCP_PORT}
  12 MYEXIT=$?
  13 
  14 : <<EXPLANATION
  15 If bash was compiled with --enable-net-redirections, it has the capability of
  16 using a special character device for both TCP and UDP redirections. These
  17 redirections are used identically as STDIN/STDOUT/STDERR. The device entries
  18 are 30,36 for /dev/tcp:
  19 
  20   mknod /dev/tcp c 30 36
  21 
  22 >From the bash reference:
  23 /dev/tcp/host/port
  24     If host is a valid hostname or Internet address, and port is an integer
  25 port number or service name, Bash attempts to open a TCP connection to the
  26 corresponding socket.
  27 EXPLANATION
  28 
  29    
  30 if [ "X$MYEXIT" = "X0" ]; then
  31   echo "Connection successful. Exit code: $MYEXIT"
  32 else
  33   echo "Connection unsuccessful. Exit code: $MYEXIT"
  34 fi
  35 
  36 exit $MYEXIT

译者补充上面这个例子输出的解释(EXPLANATION)译文:

如果bash以--enable-net-redirections选项来编译,它就拥有了使用一个特殊字符设备来完成TCP和UDP重定向功能的能力。这种重定向能力就像STDIN/STDOUT/STDERR一样被标识。该字符设备/dev/tcp的主次设备号是30,36:

mknod /dev/tcp c 30 36

>摘自bash参考手册:

/dev/tcp/host/port

如果host是一个有效的主机名或因特网有效地址,并且port是一个整数的端口号或是服务名称,Bash会尝试打开一个相对应的TCP连接socket.

[1]

在/dev目录中的条目是为各种物理设备和虚拟设备提供的挂载点. 这些条目使用非常少的设备空间.

一些像/dev/null, /dev/zero, 和 /dev/urandom的设备是虚拟的. 它们不是真正的物理设备,而只是存在于软件的虚拟设备.

[2]

块设备读或写(或两者兼之)数据都是以块为单位的进行的, 与之相对应的字符设备则使用字符为单位来进行存取。块设备典型的有硬盘和CD-ROM设备,字符设备典型的例子如键盘。

[3]

当然,挂载点/mnt/flashdrive必须存在,如果不存在,以root用户来执行mkdir /mnt/flashdrive.

为了最终能挂载设备,用下面的命令: mount /mnt/flashdrive

较新的Linux发行版自动把闪盘设备挂载到/media目录.

[4]

socket是一种特殊的用于通信的I/O端口. 它允许同一台主机内不同硬件设备间的数据传输,允许在相同网络中的主机间的数据传输,也允许穿越不同网络的主机间的数据传输,当然,也允许在Internet上不同位置主机间的数据传输.