⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zeros.html

📁 BASH Shell 编程 经典教程 《高级SHELL脚本编程》中文版
💻 HTML
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><HTML><HEAD><TITLE>Zero与Null</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINKREL="HOME"TITLE="高级Bash脚本编程指南"HREF="index.html"><LINKREL="UP"TITLE="高级主题"HREF="part4.html"><LINKREL="PREVIOUS"TITLE="/proc"HREF="procref1.html"><LINKREL="NEXT"TITLE="调试"HREF="debugging.html"></HEAD><BODYCLASS="CHAPTER"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">高级Bash脚本编程指南: 一本深入学习shell脚本艺术的书籍</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="procref1.html"ACCESSKEY="P">前一页</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="debugging.html"ACCESSKEY="N">下一页</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1><ANAME="ZEROS"></A>28. Zero与Null</H1><P><ANAME="ZEROSREF"></A></P><P></P><DIVCLASS="VARIABLELIST"><P><B><ANAME="ZERONULL1"></A><TTCLASS="FILENAME">/dev/zero</TT>与<TTCLASS="FILENAME">/dev/null</TT></B></P><DL><DT>使用<TTCLASS="FILENAME">/dev/null</TT></DT><DD><P>可以把<TTCLASS="FILENAME">/dev/null</TT>想象为一个<SPANCLASS="QUOTE">"黑洞"</SPAN>. 		它非常接近于一个只写文件. 		所有写入它的内容都会永远丢失. 		而如果想从它那读取内容, 则什么也读不到. 		但是, 对于命令行和脚本来说, 		<TTCLASS="FILENAME">/dev/null</TT>却非常的有用. 		</P><P>禁用<TTCLASS="FILENAME">stdout</TT>. 	      <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;cat $filename &#62;/dev/null  2&nbsp;# 文件的内容不会输出到stdout. </PRE></FONT></TD></TR></TABLE>            </P><P>禁用<TTCLASS="FILENAME">stderr</TT>	      (来自于<AHREF="moreadv.html#EX57">例子 12-3</A>).	      <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;rm $badname 2&#62;/dev/null  2&nbsp;#           错误消息[stderr]就这么被丢到太平洋去了. </PRE></FONT></TD></TR></TABLE>	    </P><P>禁用<TTCLASS="FILENAME">stdout</TT>和<TTCLASS="FILENAME">stderr</TT>. 	      <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;cat $filename 2&#62;/dev/null &#62;/dev/null  2&nbsp;# 如果"$filename"不存在, 将不会有错误消息输出.   3&nbsp;# 如果"$filename"存在, 文件内容不会输出到stdout.   4&nbsp;# 因此, 上边的代码根本不会产生任何输出.   5&nbsp;#  6&nbsp;#  如果你只想测试一下命令的返回码, 而不想要任何输出时,   7&nbsp;#+ 这么做就非常有用了.   8&nbsp;#  9&nbsp;# cat $filename &#38;&#62;/dev/null 10&nbsp;#     也可以, 由Baris Cicek指出. </PRE></FONT></TD></TR></TABLE>	    </P><P>删除一个文件的内容, 但是保留文件本身, 	      并且保留所有的文件访问权限(来自于<AHREF="sha-bang.html#EX1">例子 2-1</A>和<AHREF="sha-bang.html#EX2">例子 2-3</A>): 	      <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;cat /dev/null &#62; /var/log/messages  2&nbsp;#  : &#62; /var/log/messages   具有同样的效果, 但是不会产生新进程.(译者注: 因为是内建的)  3&nbsp;  4&nbsp;cat /dev/null &#62; /var/log/wtmp</PRE></FONT></TD></TR></TABLE>	      </P><P>自动清空日志文件的内容(特别适用于处理那些由商业站点发送的, 			  令人厌恶的<SPANCLASS="QUOTE">"cookie"</SPAN>):</P><DIVCLASS="EXAMPLE"><HR><ANAME="COOKIES"></A><P><B>例子 28-1. 隐藏令人厌恶的cookie</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;if [ -f ~/.netscape/cookies ]  # 如果存在, 就删除.   2&nbsp;then  3&nbsp;  rm -f ~/.netscape/cookies  4&nbsp;fi  5&nbsp;  6&nbsp;ln -s /dev/null ~/.netscape/cookies  7&nbsp;# 现在所有的cookie都被扔到黑洞里去了, 这样就不会保存在我们的磁盘中了. </PRE></FONT></TD></TR></TABLE><HR></DIV></DD><DT><ANAME="ZEROSREF1"></A>使用<TTCLASS="FILENAME">/dev/zero</TT></DT><DD><P>类似于<TTCLASS="FILENAME">/dev/null</TT>, 	      <TTCLASS="FILENAME">/dev/zero</TT>也是一个伪文件, 	      但事实上它会产生一个null流(二进制的0流, 		  而不是ASCII类型). 如果你想把其他命令的输出写入它的话, 		  那么写入的内容会消失, 		  而且如果你想从<TTCLASS="FILENAME">/dev/zero</TT>中读取一连串null的话, 		  也非常的困难, 虽然可以使用<AHREF="extmisc.html#ODREF">od</A>或者一个16进制编辑器来达到这个目的. 	<TTCLASS="FILENAME">/dev/zero</TT>的主要用途就是用来创建一个指定长度, 	并且初始化为空的文件, 这种文件一般都用作临时交换文件. 	      </P><DIVCLASS="EXAMPLE"><HR><ANAME="EX73"></A><P><B>例子 28-2. 使用<TTCLASS="FILENAME">/dev/zero</TT>来建立一个交换文件</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# 创建一个交换文件.   3&nbsp;  4&nbsp;ROOT_UID=0         # Root用户的$UID为0.   5&nbsp;E_WRONG_USER=65    # 不是root?  6&nbsp;  7&nbsp;FILE=/swap  8&nbsp;BLOCKSIZE=1024  9&nbsp;MINBLOCKS=40 10&nbsp;SUCCESS=0 11&nbsp; 12&nbsp; 13&nbsp;# 这个脚本必须以root身份来运行.  14&nbsp;if [ "$UID" -ne "$ROOT_UID" ] 15&nbsp;then 16&nbsp;  echo; echo "You must be root to run this script."; echo 17&nbsp;  exit $E_WRONG_USER 18&nbsp;fi   19&nbsp;   20&nbsp; 21&nbsp;blocks=${1:-$MINBLOCKS}          #  如果没在命令行上指定,  22&nbsp;                                 #+ 默认设置为40块.  23&nbsp;# 上边这句等价于下面这个命令块.  24&nbsp;# -------------------------------------------------- 25&nbsp;# if [ -n "$1" ] 26&nbsp;# then 27&nbsp;#   blocks=$1 28&nbsp;# else 29&nbsp;#   blocks=$MINBLOCKS 30&nbsp;# fi 31&nbsp;# -------------------------------------------------- 32&nbsp; 33&nbsp; 34&nbsp;if [ "$blocks" -lt $MINBLOCKS ] 35&nbsp;then 36&nbsp;  blocks=$MINBLOCKS              # 至少要有40块.  37&nbsp;fi   38&nbsp; 39&nbsp; 40&nbsp;echo "Creating swap file of size $blocks blocks (KB)." 41&nbsp;dd if=/dev/zero of=$FILE bs=$BLOCKSIZE count=$blocks  # 用零填充文件.  42&nbsp; 43&nbsp;mkswap $FILE $blocks             # 将其指定为交换文件(译者注: 或称为交换分区).  44&nbsp;swapon $FILE                     # 激活交换文件.  45&nbsp; 46&nbsp;echo "Swap file created and activated." 47&nbsp; 48&nbsp;exit $SUCCESS</PRE></FONT></TD></TR></TABLE><HR></DIV><P><TTCLASS="FILENAME">/dev/zero</TT>还有其他的应用场合, 	      比如当你出于特殊目的, 需要<SPANCLASS="QUOTE">"用0填充"</SPAN>一个指定大小的文件时, 就可以使用它. 		  举个例子, 比如要将一个文件系统挂载到<AHREF="devref1.html#LOOPBACKREF">环回设备(loopback device)</A>上(请参考<AHREF="system.html#CREATEFS">例子 13-8</A>), 		 或者想<SPANCLASS="QUOTE">"安全"</SPAN>的删除一个文件(请参考<AHREF="extmisc.html#BLOTOUT">例子 12-55</A>). </P><DIVCLASS="EXAMPLE"><HR><ANAME="RAMDISK"></A><P><B>例子 28-3. 创建一个ramdisk</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><FONTCOLOR="#000000"><PRECLASS="PROGRAMLISTING">  1&nbsp;#!/bin/bash  2&nbsp;# ramdisk.sh  3&nbsp;  4&nbsp;#  一个"ramdisk"就是系统RAM内存中的一部分,   5&nbsp;#+ 只不过它被当作文件系统来操作.   6&nbsp;#  它的优点是访问速度非常快(读/写时间快).   7&nbsp;#  缺点: 易失性, 当机器重启或关机时, 会丢失数组.   8&nbsp;#+                而且会减少系统可用的RAM.   9&nbsp;# 10&nbsp;#  那么ramdisk有什么用呢?  11&nbsp;#  保存一个大数据集, 比如保存表格或字典.  12&nbsp;#+ 这样的话, 可以增加查询速度, 因为访问内存比访问硬盘快得多.  13&nbsp; 14&nbsp; 15&nbsp;E_NON_ROOT_USER=70             # 必须以root身份来运行.  16&nbsp;ROOTUSER_NAME=root 17&nbsp; 18&nbsp;MOUNTPT=/mnt/ramdisk 19&nbsp;SIZE=2000                      # 2K个块(可以进行适当的修改) 20&nbsp;BLOCKSIZE=1024                 # 每块的大小为1K(1024字节) 21&nbsp;DEVICE=/dev/ram0               # 第一个ram设备 22&nbsp; 23&nbsp;username=`id -nu` 24&nbsp;if [ "$username" != "$ROOTUSER_NAME" ] 25&nbsp;then 26&nbsp;  echo "Must be root to run \"`basename $0`\"." 27&nbsp;  exit $E_NON_ROOT_USER 28&nbsp;fi 29&nbsp; 30&nbsp;if [ ! -d "$MOUNTPT" ]         #  测试挂载点是否已经存在,  31&nbsp;then                           #+ 如果做了这个判断的话, 当脚本运行多次的时候,  32&nbsp;  mkdir $MOUNTPT               #+ 就不会报错了. (译者注: 主要是为了避免多次创建目录.) 33&nbsp;fi 34&nbsp; 35&nbsp;dd if=/dev/zero of=$DEVICE count=$SIZE bs=$BLOCKSIZE  # 把RAM设备的内容用0填充.  36&nbsp;                                                      # 为什么必须这么做?  37&nbsp;mke2fs $DEVICE                 # 在RAM上创建一个ext2文件系统.  38&nbsp;mount $DEVICE $MOUNTPT         # 挂载上.  39&nbsp;chmod 777 $MOUNTPT             # 使一般用户也可以访问这个ramdisk.  40&nbsp;                               # 然而, 只能使用root身份来卸载它.  41&nbsp; 42&nbsp;echo "\"$MOUNTPT\" now available for use." 43&nbsp;# 现在ramdisk就可以访问了, 即使是普通用户也可以访问.  44&nbsp; 45&nbsp;#  小心, ramdisk存在易失性,  46&nbsp;#+ 如果重启或关机的话, 保存的内容就会消失.  47&nbsp;#  所以, 还是要将你想保存的文件, 保存到常规磁盘目录下.  48&nbsp; 49&nbsp;# 重启之后, 运行这个脚本, 将会再次建立一个ramdisk.  50&nbsp;# 如果你仅仅重新加载/mnt/ramdisk, 而没有运行其他步骤的话, 那就不会正常工作.  51&nbsp; 52&nbsp;#  如果对这个脚本进行适当的改进, 就可以将其放入/etc/rc.d/rc.local中,  53&nbsp;#+ 这样, 在系统启动的时候就会自动建立一个ramdisk.  54&nbsp;#  这么做非常适合于那些对速度要求很高的数据库服务器.  55&nbsp; 56&nbsp;exit 0</PRE></FONT></TD></TR></TABLE><HR></DIV><P>最后值得一提的是, 	      ELF二进制文件需要使用<TTCLASS="FILENAME">/dev/zero</TT>. </P></DD></DL></DIV></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="procref1.html"ACCESSKEY="P">前一页</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html"ACCESSKEY="H">首页</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="debugging.html"ACCESSKEY="N">下一页</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><TTCLASS="FILENAME">/proc</TT></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="part4.html"ACCESSKEY="U">上一级</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">调试</TD></TR></TABLE></DIV></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -