可以把/dev/null想象为一个"黑洞". 它非常接近于一个只写文件. 所有写入它的内容都会永远丢失. 而如果想从它那读取内容, 则什么也读不到. 但是, 对于命令行和脚本来说, /dev/null却非常的有用.
禁用stdout.
1 cat $filename >/dev/null 2 # 文件的内容不会输出到stdout. |
禁用stderr (来自于例子 12-3).
1 rm $badname 2>/dev/null 2 # 错误消息[stderr]就这么被丢到太平洋去了. |
禁用stdout和stderr.
1 cat $filename 2>/dev/null >/dev/null 2 # 如果"$filename"不存在, 将不会有错误消息输出. 3 # 如果"$filename"存在, 文件内容不会输出到stdout. 4 # 因此, 上边的代码根本不会产生任何输出. 5 # 6 # 如果你只想测试一下命令的返回码, 而不想要任何输出时, 7 #+ 这么做就非常有用了. 8 # 9 # cat $filename &>/dev/null 10 # 也可以, 由Baris Cicek指出. |
删除一个文件的内容, 但是保留文件本身, 并且保留所有的文件访问权限(来自于例子 2-1和例子 2-3):
1 cat /dev/null > /var/log/messages 2 # : > /var/log/messages 具有同样的效果, 但是不会产生新进程.(译者注: 因为是内建的) 3 4 cat /dev/null > /var/log/wtmp |
自动清空日志文件的内容(特别适用于处理那些由商业站点发送的, 令人厌恶的"cookie"):
类似于/dev/null, /dev/zero也是一个伪文件, 但事实上它会产生一个null流(二进制的0流, 而不是ASCII类型). 如果你想把其他命令的输出写入它的话, 那么写入的内容会消失, 而且如果你想从/dev/zero中读取一连串null的话, 也非常的困难, 虽然可以使用od或者一个16进制编辑器来达到这个目的. /dev/zero的主要用途就是用来创建一个指定长度, 并且初始化为空的文件, 这种文件一般都用作临时交换文件.
例子 28-2. 使用/dev/zero来建立一个交换文件
1 #!/bin/bash 2 # 创建一个交换文件. 3 4 ROOT_UID=0 # Root用户的$UID为0. 5 E_WRONG_USER=65 # 不是root? 6 7 FILE=/swap 8 BLOCKSIZE=1024 9 MINBLOCKS=40 10 SUCCESS=0 11 12 13 # 这个脚本必须以root身份来运行. 14 if [ "$UID" -ne "$ROOT_UID" ] 15 then 16 echo; echo "You must be root to run this script."; echo 17 exit $E_WRONG_USER 18 fi 19 20 21 blocks=${1:-$MINBLOCKS} # 如果没在命令行上指定, 22 #+ 默认设置为40块. 23 # 上边这句等价于下面这个命令块. 24 # -------------------------------------------------- 25 # if [ -n "$1" ] 26 # then 27 # blocks=$1 28 # else 29 # blocks=$MINBLOCKS 30 # fi 31 # -------------------------------------------------- 32 33 34 if [ "$blocks" -lt $MINBLOCKS ] 35 then 36 blocks=$MINBLOCKS # 至少要有40块. 37 fi 38 39 40 echo "Creating swap file of size $blocks blocks (KB)." 41 dd if=/dev/zero of=$FILE bs=$BLOCKSIZE count=$blocks # 用零填充文件. 42 43 mkswap $FILE $blocks # 将其指定为交换文件(译者注: 或称为交换分区). 44 swapon $FILE # 激活交换文件. 45 46 echo "Swap file created and activated." 47 48 exit $SUCCESS |
/dev/zero还有其他的应用场合, 比如当你出于特殊目的, 需要"用0填充"一个指定大小的文件时, 就可以使用它. 举个例子, 比如要将一个文件系统挂载到环回设备(loopback device)上(请参考例子 13-8), 或者想"安全"的删除一个文件(请参考例子 12-55).
例子 28-3. 创建一个ramdisk
1 #!/bin/bash 2 # ramdisk.sh 3 4 # 一个"ramdisk"就是系统RAM内存中的一部分, 5 #+ 只不过它被当作文件系统来操作. 6 # 它的优点是访问速度非常快(读/写时间快). 7 # 缺点: 易失性, 当机器重启或关机时, 会丢失数组. 8 #+ 而且会减少系统可用的RAM. 9 # 10 # 那么ramdisk有什么用呢? 11 # 保存一个大数据集, 比如保存表格或字典. 12 #+ 这样的话, 可以增加查询速度, 因为访问内存比访问硬盘快得多. 13 14 15 E_NON_ROOT_USER=70 # 必须以root身份来运行. 16 ROOTUSER_NAME=root 17 18 MOUNTPT=/mnt/ramdisk 19 SIZE=2000 # 2K个块(可以进行适当的修改) 20 BLOCKSIZE=1024 # 每块的大小为1K(1024字节) 21 DEVICE=/dev/ram0 # 第一个ram设备 22 23 username=`id -nu` 24 if [ "$username" != "$ROOTUSER_NAME" ] 25 then 26 echo "Must be root to run \"`basename $0`\"." 27 exit $E_NON_ROOT_USER 28 fi 29 30 if [ ! -d "$MOUNTPT" ] # 测试挂载点是否已经存在, 31 then #+ 如果做了这个判断的话, 当脚本运行多次的时候, 32 mkdir $MOUNTPT #+ 就不会报错了. (译者注: 主要是为了避免多次创建目录.) 33 fi 34 35 dd if=/dev/zero of=$DEVICE count=$SIZE bs=$BLOCKSIZE # 把RAM设备的内容用0填充. 36 # 为什么必须这么做? 37 mke2fs $DEVICE # 在RAM上创建一个ext2文件系统. 38 mount $DEVICE $MOUNTPT # 挂载上. 39 chmod 777 $MOUNTPT # 使一般用户也可以访问这个ramdisk. 40 # 然而, 只能使用root身份来卸载它. 41 42 echo "\"$MOUNTPT\" now available for use." 43 # 现在ramdisk就可以访问了, 即使是普通用户也可以访问. 44 45 # 小心, ramdisk存在易失性, 46 #+ 如果重启或关机的话, 保存的内容就会消失. 47 # 所以, 还是要将你想保存的文件, 保存到常规磁盘目录下. 48 49 # 重启之后, 运行这个脚本, 将会再次建立一个ramdisk. 50 # 如果你仅仅重新加载/mnt/ramdisk, 而没有运行其他步骤的话, 那就不会正常工作. 51 52 # 如果对这个脚本进行适当的改进, 就可以将其放入/etc/rc.d/rc.local中, 53 #+ 这样, 在系统启动的时候就会自动建立一个ramdisk. 54 # 这么做非常适合于那些对速度要求很高的数据库服务器. 55 56 exit 0 |
最后值得一提的是, ELF二进制文件需要使用/dev/zero.