Standard UNIX commands make shell scripts more versatile. The power of scripts comes from coupling system commands and shell directives with simple programming constructs.
The first commands a novice learns
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, 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. |
See also Example 12-24 and Example 12-20.
In a pipe, it may be more efficient to redirect the stdin to a file, rather than to cat the file.
|
tac, is the inverse of cat, listing a file backwards from its end.
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 |
This is the file copy command. cp file1 file2 copies file1 to file2, overwriting file2 if it already exists (see Example 12-6).
Particularly useful are the -a archive flag (for copying an entire directory tree) and the -r and -R recursive flags. |
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.
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.
|
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.
The rm command will, by itself, fail to remove filenames beginning with a dash.
The way to accomplish this is to preface the filename to be removed with a dot-slash .
|
When used with the recursive flag -r, this command removes files all the way down the directory tree from the current directory. |
Remove directory. The directory must be empty of all files, including invisible "dotfiles", [1] for this command to succeed.
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.
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. |
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.
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.
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 |
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.
[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. |