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目录也包含环回设备, 比如/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-24.)

当在/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
	      

[感谢, 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                # 端口80是http. 
  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

译者注: 由于上边例子的输出大部分都是英文, 所以译者补充一下脚本输出的译文.

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

  1 mknod /dev/tcp c 30 36

>摘自bash参考手册:

/dev/tcp/host/port

如果host是一个有效的主机名或Internet地址, 并且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上的不同地区之间的不同主机之间传输.