📄 zeros.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><TITLE>Of Zeros and Nulls</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+"><LINKREL="HOME"TITLE="Advanced Bash-Scripting Guide"HREF="index.html"><LINKREL="UP"TITLE="Advanced Topics"HREF="part5.html"><LINKREL="PREVIOUS"TITLE="/proc"HREF="procref1.html"><LINKREL="NEXT"TITLE="Debugging"HREF="debugging.html"><METAHTTP-EQUIV="Content-Style-Type"CONTENT="text/css"><LINKREL="stylesheet"HREF="common/kde-common.css"TYPE="text/css"><METAHTTP-EQUIV="Content-Type"CONTENT="text/html; charset=iso-8859-1"><METAHTTP-EQUIV="Content-Language"CONTENT="en"><LINKREL="stylesheet"HREF="common/kde-localised.css"TYPE="text/css"TITLE="KDE-English"><LINKREL="stylesheet"HREF="common/kde-default.css"TYPE="text/css"TITLE="KDE-Default"></HEAD><BODYCLASS="CHAPTER"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#AA0000"VLINK="#AA0055"ALINK="#AA0000"STYLE="font-family: sans-serif;"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="procref1.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="debugging.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1><ANAME="ZEROS"></A>Chapter 28. Of Zeros and Nulls</H1><P><ANAME="ZEROSREF"></A></P><DIVCLASS="VARIABLELIST"><P><B><ANAME="ZERONULL1"></A><TTCLASS="FILENAME">/dev/zero</TT> and <TTCLASS="FILENAME">/dev/null</TT></B></P><DL><DT><ANAME="DEVNULLREF"></A>Uses of <TTCLASS="FILENAME">/dev/null</TT></DT><DD><P>Think of <TTCLASS="FILENAME">/dev/null</TT> as a <SPANCLASS="QUOTE">"black hole."</SPAN> It is the nearest equivalent to a write-only file. Everything written to it disappears forever. Attempts to read or output from it result in nothing. Nevertheless, <TTCLASS="FILENAME">/dev/null</TT> can be quite useful from both the command line and in scripts.</P><P>Suppressing <TTCLASS="FILENAME">stdout</TT>. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 cat $filename >/dev/null 2 # Contents of the file will not list to stdout.</PRE></TD></TR></TABLE> </P><P>Suppressing <TTCLASS="FILENAME">stderr</TT> (from <AHREF="moreadv.html#EX57">Example 15-3</A>). <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 rm $badname 2>/dev/null 2 # So error messages [stderr] deep-sixed.</PRE></TD></TR></TABLE> </P><P>Suppressing output from <SPANCLASS="emphasis"><ICLASS="EMPHASIS">both</I></SPAN> <TTCLASS="FILENAME">stdout</TT> and <TTCLASS="FILENAME">stderr</TT>. <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 cat $filename 2>/dev/null >/dev/null 2 # If "$filename" does not exist, there will be no error message output. 3 # If "$filename" does exist, the contents of the file will not list to stdout. 4 # Therefore, no output at all will result from the above line of code. 5 # 6 # This can be useful in situations where the return code from a command 7 #+ needs to be tested, but no output is desired. 8 # 9 # cat $filename &>/dev/null 10 # also works, as Baris Cicek points out.</PRE></TD></TR></TABLE> </P><P>Deleting contents of a file, but preserving the file itself, with all attendant permissions (from <AHREF="sha-bang.html#EX1">Example 2-1</A> and <AHREF="sha-bang.html#EX2">Example 2-3</A>): <TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 cat /dev/null > /var/log/messages 2 # : > /var/log/messages has same effect, but does not spawn a new process. 3 4 cat /dev/null > /var/log/wtmp</PRE></TD></TR></TABLE> </P><P>Automatically emptying the contents of a logfile (especially good for dealing with those nasty <SPANCLASS="QUOTE">"cookies"</SPAN> sent by commercial Web sites):</P><DIVCLASS="EXAMPLE"><HR><ANAME="COOKIES"></A><P><B>Example 28-1. Hiding the cookie jar</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 if [ -f ~/.netscape/cookies ] # Remove, if exists. 2 then 3 rm -f ~/.netscape/cookies 4 fi 5 6 ln -s /dev/null ~/.netscape/cookies 7 # All cookies now get sent to a black hole, rather than saved to disk.</PRE></TD></TR></TABLE><HR></DIV></DD><DT><ANAME="ZEROSREF1"></A>Uses of <TTCLASS="FILENAME">/dev/zero</TT></DT><DD><P>Like <TTCLASS="FILENAME">/dev/null</TT>, <TTCLASS="FILENAME">/dev/zero</TT> is a pseudo-device file, but it actually produces a stream of nulls (<SPANCLASS="emphasis"><ICLASS="EMPHASIS">binary</I></SPAN> zeros, not the ASCII kind). Output written to <TTCLASS="FILENAME">/dev/zero</TT> disappears, and it is fairly difficult to actually read the nulls from there, though it can be done with <AHREF="extmisc.html#ODREF">od</A> or a hex editor. <ANAME="SWAPFILEREF"></A>The chief use for <TTCLASS="FILENAME">/dev/zero</TT> is in creating an initialized dummy file of predetermined length intended as a temporary swap file.</P><DIVCLASS="EXAMPLE"><HR><ANAME="EX73"></A><P><B>Example 28-2. Setting up a swapfile using <TTCLASS="FILENAME">/dev/zero</TT></B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # Creating a swapfile. 3 4 ROOT_UID=0 # Root has $UID 0. 5 E_WRONG_USER=65 # Not root? 6 7 FILE=/swap 8 BLOCKSIZE=1024 9 MINBLOCKS=40 10 SUCCESS=0 11 12 13 # This script must be run as 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} # Set to default of 40 blocks, 22 #+ if nothing specified on command line. 23 # This is the equivalent of the command block below. 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 # Must be at least 40 blocks long. 37 fi 38 39 40 ###################################################################### 41 echo "Creating swap file of size $blocks blocks (KB)." 42 dd if=/dev/zero of=$FILE bs=$BLOCKSIZE count=$blocks # Zero out file. 43 mkswap $FILE $blocks # Designate it a swap file. 44 swapon $FILE # Activate swap file. 45 # Note that if one or more of these commands fails, 46 #+ then it could cause nasty problems. 47 ###################################################################### 48 49 # Exercise: 50 # Rewrite the above block of code so that if it does not execute 51 #+ successfully, then: 52 # 1) an error message is echoed to stderr, 53 # 2) all temporary files are cleaned up, and 54 # 3) the script exits in an orderly fashion with an 55 #+ appropriate error code. 56 57 echo "Swap file created and activated." 58 59 exit $SUCCESS</PRE></TD></TR></TABLE><HR></DIV><P>Another application of <TTCLASS="FILENAME">/dev/zero</TT> is to <SPANCLASS="QUOTE">"zero out"</SPAN> a file of a designated size for a special purpose, such as mounting a filesystem on a <AHREF="devproc.html#LOOPBACKREF">loopback device</A> (see <AHREF="system.html#CREATEFS">Example 16-8</A>) or <SPANCLASS="QUOTE">"securely"</SPAN> deleting a file (see <AHREF="extmisc.html#BLOTOUT">Example 15-58</A>).</P><DIVCLASS="EXAMPLE"><HR><ANAME="RAMDISK"></A><P><B>Example 28-3. Creating a ramdisk</B></P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="90%"><TR><TD><PRECLASS="PROGRAMLISTING"> 1 #!/bin/bash 2 # ramdisk.sh 3 4 # A "ramdisk" is a segment of system RAM memory 5 #+ which acts as if it were a filesystem. 6 # Its advantage is very fast access (read/write time). 7 # Disadvantages: volatility, loss of data on reboot or powerdown. 8 #+ less RAM available to system. 9 # 10 # Of what use is a ramdisk? 11 # Keeping a large dataset, such as a table or dictionary on ramdisk, 12 #+ speeds up data lookup, since memory access is much faster than disk access. 13 14 15 E_NON_ROOT_USER=70 # Must run as root. 16 ROOTUSER_NAME=root 17 18 MOUNTPT=/mnt/ramdisk 19 SIZE=2000 # 2K blocks (change as appropriate) 20 BLOCKSIZE=1024 # 1K (1024 byte) block size 21 DEVICE=/dev/ram0 # First ram device 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" ] # Test whether mount point already there, 31 then #+ so no error if this script is run 32 mkdir $MOUNTPT #+ multiple times. 33 fi 34 35 ############################################################################## 36 dd if=/dev/zero of=$DEVICE count=$SIZE bs=$BLOCKSIZE # Zero out RAM device. 37 # Why is this necessary? 38 mke2fs $DEVICE # Create an ext2 filesystem on it. 39 mount $DEVICE $MOUNTPT # Mount it. 40 chmod 777 $MOUNTPT # Enables ordinary user to access ramdisk. 41 # However, must be root to unmount it. 42 ############################################################################## 43 # Need to test whether above commands succeed. Could cause problems otherwise. 44 # Exercise: modify this script to make it safer. 45 46 echo "\"$MOUNTPT\" now available for use." 47 # The ramdisk is now accessible for storing files, even by an ordinary user. 48 49 # Caution, the ramdisk is volatile, and its contents will disappear 50 #+ on reboot or power loss. 51 # Copy anything you want saved to a regular directory. 52 53 # After reboot, run this script to again set up ramdisk. 54 # Remounting /mnt/ramdisk without the other steps will not work. 55 56 # Suitably modified, this script can by invoked in /etc/rc.d/rc.local, 57 #+ to set up ramdisk automatically at bootup. 58 # That may be appropriate on, for example, a database server. 59 60 exit 0</PRE></TD></TR></TABLE><HR></DIV><P>In addition to all the above, <TTCLASS="FILENAME">/dev/zero</TT> is needed by ELF binaries.</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">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="index.html"ACCESSKEY="H">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="debugging.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><TTCLASS="FILENAME">/proc</TT></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="part5.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Debugging</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -