Chapter 12. External Filters, Programs and Commands

Standard UNIX commands make shell scripts more versatile. The power of scripts comes from coupling system commands and shell directives with simple programming constructs.

12.1. Basic Commands

The first commands a novice learns

ls

The basic file "list" command. It is all too easy to underestimate the power of this humble command. For example, using the -R, recursive option, ls provides a tree-like listing of a directory structure. Other useful options are -S, sort listing by file size, -t, sort by file modification time, and -i, show file inodes (see Example 12-4).


Example 12-1. Using ls to create a table of contents for burning a CDR disk

   1 #!/bin/bash
   2 # burn-cd.sh
   3 # Script to automate burning a CDR.
   4 
   5 
   6 SPEED=2          # May use higher speed if your hardware supports it.
   7 IMAGEFILE=cdimage.iso
   8 CONTENTSFILE=contents
   9 DEVICE=cdrom
  10 # DEVICE="0,0"     for older versions of cdrecord
  11 DEFAULTDIR=/opt  # This is the directory containing the data to be burned.
  12                  # Make sure it exists.
  13                  # Exercise: Add a test for this.
  14 
  15 # Uses Joerg Schilling's "cdrecord" package:
  16 # http://www.fokus.fhg.de/usr/schilling/cdrecord.html
  17 
  18 #  If this script invoked as an ordinary user, need to suid cdrecord
  19 #+ chmod u+s /usr/bin/cdrecord, as root.
  20 #  Of course, this creates a security hole, though a relatively minor one.
  21 
  22 if [ -z "$1" ]
  23 then
  24   IMAGE_DIRECTORY=$DEFAULTDIR
  25   # Default directory, if not specified on command line.
  26 else
  27     IMAGE_DIRECTORY=$1
  28 fi
  29 
  30 # Create a "table of contents" file.
  31 ls -lRF $IMAGE_DIRECTORY > $IMAGE_DIRECTORY/$CONTENTSFILE
  32 # The "l" option gives a "long" file listing.
  33 # The "R" option makes the listing recursive.
  34 # The "F" option marks the file types (directories get a trailing /).
  35 echo "Creating table of contents."
  36 
  37 # Create an image file preparatory to burning it onto the CDR.
  38 mkisofs -r -o $IMAGEFILE $IMAGE_DIRECTORY
  39 echo "Creating ISO9660 file system image ($IMAGEFILE)."
  40 
  41 # Burn the CDR.
  42 cdrecord -v -isosize speed=$SPEED dev=$DEVICE $IMAGEFILE
  43 echo "Burning the disk."
  44 echo "Please be patient, this will take a while."
  45 
  46 exit 0

cat, tac

cat, an acronym for concatenate, lists a file to stdout. When combined with redirection (> or >>), it is commonly used to concatenate files.
   1 # Uses of 'cat'
   2 cat filename                          # Lists the file.
   3 
   4 cat file.1 file.2 file.3 > file.123   # Combines three files into one.
The -n option to cat inserts consecutive numbers before all lines of the target file(s). The -b option numbers only the non-blank lines. The -v option echoes nonprintable characters, using ^ notation. The -s option squeezes multiple consecutive blank lines into a single blank line.

See also Example 12-24 and Example 12-20.

Note

In a pipe, it may be more efficient to redirect the stdin to a file, rather than to cat the file.

   1 cat filename | tr a-z A-Z
   2 
   3 tr a-z A-Z < filename   #  Same effect, but starts one less process,
   4                         #+ and also dispenses with the pipe.

tac, is the inverse of cat, listing a file backwards from its end.

rev

reverses each line of a file, and outputs to stdout. This is not the same effect as tac, as it preserves the order of the lines, but flips each one around.

 bash$ cat file1.txt
 This is line 1.
 This is line 2.
 
 
 bash$ tac file1.txt
 This is line 2.
 This is line 1.
 
 
 bash$ rev file1.txt
 .1 enil si sihT
 .2 enil si sihT
 	      

cp

This is the file copy command. cp file1 file2 copies file1 to file2, overwriting file2 if it already exists (see Example 12-6).

Tip

Particularly useful are the -a archive flag (for copying an entire directory tree) and the -r and -R recursive flags.

mv

This is the file move command. It is equivalent to a combination of cp and rm. It may be used to move multiple files to a directory, or even to rename a directory. For some examples of using mv in a script, see Example 9-17 and Example A-2.

Note

When used in a non-interactive script, mv takes the -f (force) option to bypass user input.

When a directory is moved to a preexisting directory, it becomes a subdirectory of the destination directory.

 bash$ mv source_directory target_directory
 
 bash$ ls -lF target_directory
 total 1
 drwxrwxr-x    2 bozo  bozo      1024 May 28 19:20 source_directory/
 	      

rm

Delete (remove) a file or files. The -f option forces removal of even readonly files, and is useful for bypassing user input in a script.

Note

The rm command will, by itself, fail to remove filenames beginning with a dash.

 bash$ rm -badname
 rm: invalid option -- b
 Try `rm --help' for more information.

The way to accomplish this is to preface the filename to be removed with a dot-slash .

 bash$ rm ./-badname

Warning

When used with the recursive flag -r, this command removes files all the way down the directory tree from the current directory.

rmdir

Remove directory. The directory must be empty of all files, including invisible "dotfiles", [1] for this command to succeed.

mkdir

Make directory, creates a new directory. For example, mkdir -p project/programs/December creates the named directory. The -p option automatically creates any necessary parent directories.

chmod

Changes the attributes of an existing file (see Example 11-11).

   1 chmod +x filename
   2 # Makes "filename" executable for all users.
   3 
   4 chmod u+s filename
   5 # Sets "suid" bit on "filename" permissions.
   6 # An ordinary user may execute "filename" with same privileges as the file's owner.
   7 # (This does not apply to shell scripts.)

   1 chmod 644 filename
   2 # Makes "filename" readable/writable to owner, readable to
   3 # others
   4 # (octal mode).

   1 chmod 1777 directory-name
   2 # Gives everyone read, write, and execute permission in directory,
   3 # however also sets the "sticky bit".
   4 # This means that only the owner of the directory,
   5 # owner of the file, and, of course, root
   6 # can delete any particular file in that directory.

chattr

Change file attributes. This has the same effect as chmod above, but with a different invocation syntax, and it works only on an ext2 filesystem.

ln

Creates links to pre-existings files. A "link" is a reference to a file, an alternate name for it. The ln command permits referencing the linked file by more than one name and is a superior alternative to aliasing (see Example 4-6).

The ln creates only a reference, a pointer to the file only a few bytes in size.

The ln command is most often used with the -s, symbolic or "soft" link flag. An advantage of using the -s flag is that it permits linking across file systems.

The syntax of the command is a bit tricky. For example: ln -s oldfile newfile links the previously existing oldfile to the newly created link, newfile.

Caution

If a file named newfile has previously existed, it will be deleted when the filename newfile is preempted as the name for a link.

Links give the ability to invoke a script (or any other type of executable) with multiple names, and having that script behave according to how it was invoked.


Example 12-2. Hello or Good-bye

   1 #!/bin/bash
   2 # hello.sh: Saying "hello" or "goodbye"
   3 #+          depending on how script is invoked.
   4 
   5 # Make a link in current working directory ($PWD) to this script:
   6 #    ln -s hello.sh goodbye
   7 # Now, try invoking this script both ways:
   8 # ./hello.sh
   9 # ./goodbye
  10 
  11 
  12 HELLO_CALL=65
  13 GOODBYE_CALL=66
  14 
  15 if [ $0 = "./goodbye" ]
  16 then
  17   echo "Good-bye!"
  18   # Some other goodbye-type commands, as appropriate.
  19   exit $GOODBYE_CALL
  20 fi
  21 
  22 echo "Hello!"
  23 # Some other hello-type commands, as appropriate.
  24 exit $HELLO_CALL

man, info

These commands access the manual and information pages on system commands and installed utilities. When available, the info pages usually contain a more detailed description than do the man pages.

Notes

[1]

These are files whose names begin with a dot, such as ~/.Xdefaults. Such filenames do not show up in a normal ls listing, and they cannot be deleted by an accidental rm -rf *. Dotfiles are generally used as setup and configuration files in a user's home directory.