Chapter 28. Of Zeros and Nulls

 

Faultily faultless, icily regular, splendidly null

Dead perfection; no more.

--Alfred, Lord Tennyson

/dev/zero ... /dev/null

Uses of /dev/null

Think of /dev/null as a black hole. It is essentially the equivalent of a write-only file. Everything written to it disappears. Attempts to read or output from it result in nothing. All the same, /dev/null can be quite useful from both the command line and in scripts.

Suppressing stdout.
   1 cat $filename >/dev/null
   2 # Contents of the file will not list to stdout.

Suppressing stderr (from Example 15-3).
   1 rm $badname 2>/dev/null
   2 #           So error messages [stderr] deep-sixed.

Suppressing output from both stdout and stderr.
   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.

Deleting contents of a file, but preserving the file itself, with all attendant permissions (from Example 2-1 and Example 2-3):
   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

Automatically emptying the contents of a logfile (especially good for dealing with those nasty "cookies" sent by commercial Web sites):


Example 28-1. Hiding the cookie jar

   1 # Obsolete Netscape browser.
   2 # Same principle applies to newer browsers.
   3 
   4 if [ -f ~/.netscape/cookies ]  # Remove, if exists.
   5 then
   6   rm -f ~/.netscape/cookies
   7 fi
   8 
   9 ln -s /dev/null ~/.netscape/cookies
  10 # All cookies now get sent to a black hole, rather than saved to disk.

Uses of /dev/zero

Like /dev/null, /dev/zero is a pseudo-device file, but it actually produces a stream of nulls (binary zeros, not the ASCII kind). Output written to /dev/zero disappears, and it is fairly difficult to actually read the nulls emitted there, though it can be done with od or a hex editor. The chief use of /dev/zero is creating an initialized dummy file of predetermined length intended as a temporary swap file.


Example 28-2. Setting up a swapfile using /dev/zero

   1 #!/bin/bash
   2 # Creating a swap file.
   3 
   4 #  A swap file provides a temporary storage cache
   5 #+ which helps speed up certain filesystem operations.
   6 
   7 ROOT_UID=0         # Root has $UID 0.
   8 E_WRONG_USER=65    # Not root?
   9 
  10 FILE=/swap
  11 BLOCKSIZE=1024
  12 MINBLOCKS=40
  13 SUCCESS=0
  14 
  15 
  16 # This script must be run as root.
  17 if [ "$UID" -ne "$ROOT_UID" ]
  18 then
  19   echo; echo "You must be root to run this script."; echo
  20   exit $E_WRONG_USER
  21 fi  
  22   
  23 
  24 blocks=${1:-$MINBLOCKS}          #  Set to default of 40 blocks,
  25                                  #+ if nothing specified on command line.
  26 # This is the equivalent of the command block below.
  27 # --------------------------------------------------
  28 # if [ -n "$1" ]
  29 # then
  30 #   blocks=$1
  31 # else
  32 #   blocks=$MINBLOCKS
  33 # fi
  34 # --------------------------------------------------
  35 
  36 
  37 if [ "$blocks" -lt $MINBLOCKS ]
  38 then
  39   blocks=$MINBLOCKS              # Must be at least 40 blocks long.
  40 fi  
  41 
  42 
  43 ######################################################################
  44 echo "Creating swap file of size $blocks blocks (KB)."
  45 dd if=/dev/zero of=$FILE bs=$BLOCKSIZE count=$blocks  # Zero out file.
  46 mkswap $FILE $blocks             # Designate it a swap file.
  47 swapon $FILE                     # Activate swap file.
  48 retcode=$?                       # Everything worked?
  49 #  Note that if one or more of these commands fails,
  50 #+ then it could cause nasty problems.
  51 ######################################################################
  52 
  53 #  Exercise:
  54 #  Rewrite the above block of code so that if it does not execute
  55 #+ successfully, then:
  56 #    1) an error message is echoed to stderr,
  57 #    2) all temporary files are cleaned up, and
  58 #    3) the script exits in an orderly fashion with an
  59 #+      appropriate error code.
  60 
  61 echo "Swap file created and activated."
  62 
  63 exit $retcode

Another application of /dev/zero is to "zero out" a file of a designated size for a special purpose, such as mounting a filesystem on a loopback device (see Example 16-8) or "securely" deleting a file (see Example 15-60).


Example 28-3. Creating a ramdisk

   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

In addition to all the above, /dev/zero is needed by ELF (Executable and Linking Format) UNIX/Linux binaries.