-->

Previous | Table of Contents | Next

Page 358

-m, --time=mtime, or --time=modify Changes modification time only
--date=time Uses time instead of current time
-r file or --reference=file Uses the times from file instead of the current time

One of the common uses of touch is to create a large number of files quickly for testing scripts that read and process filenames.

Disk Usage

The GNU disk usage utilities, df and du, are quite similar to their UNIX counterparts, but implement a few nice options that make their output much easier to read and understand.

By default, both programs produce output in terms of blocks, which varies depending on the local machine (strict POSIX machines use 512 bytes per block, while others use 1024 bytes per block), but their output can be changed to be in kilobytes, megabytes, or gigabytes. The output options are as follows:

-k or --kilobytes Prints in 1KB (1024-byte) blocks
-m or --megabytes Prints in 1MB (1,048,576 bytes) blocks
-h or --human-readable Appends a letter to indicate size (K for kilobytes, M for megabytes, G for gigabytes)

Find Utilities

The find utilities enable the user to find files that meet given criteria and perform actions on those files. The three main utilities are locate, find, and xargs. The locate and find commands are used to locate files, and xargs is used to act upon those files.

locate

The locate command is the simplest and fastest command available for finding files. It does not actually search the filesystem; instead, it searches through filename databases that contain a list of files that were in particular directory trees when the databases were last updated. Typically, the databases are updated nightly, and thus are reasonably up-to-date for executables and libraries.

The basic syntax for locate is


locate [string1 ... stringN]

Any number of files can be specified and locate will run through the database files and print out a list of matches. For example,


locate bash emacs

prints out a list of files that contain the string bash or emacs. Some matches on my system include

Page 359


/usr/bin/bashbug

/usr/local/bin/bash

/usr/local/man/man1/bash.1

/usr/lib/zoneinfo/Africa/Lumumbashi

/usr/doc/minicom-1.75-2/doc/Todo.emacskey.dif

/usr/local/bin/emacs

/usr/share/emacs/19.34/etc/emacs.1

In addition, locate will also properly handle shell wildcards. Thus,


locate *[mM]akefile

prints out a list of makefiles on the system.

If the filename databases are not being updated regularly on a system, the system administrator can update the databases by running the updatedb command manually. Usually simply running updatedb without any options and waiting for it to finish is adequate, but sometimes it is necessary to specify the directories that should and should not be included. To facilitate this, updatedb understands the following options:

--localpaths=path A list of nonnetwork directories to put in the database; the default is /.
--netpaths=path A list of network directories to put in the database; the default is none.
--prunepaths=path A list of directories not to put in the database; the default is
`/tmp /usr/tmp /var/tmp /afs'
find

The find command is much more powerful than locate and can be given extensive options to modify the search criteria. Unlike locate, find actually searches the disk (local and/or remote); thus, it is much slower, but provides the most up-to-date information. The basic syntax of
find is


find directory [options]

The most basic usage of find is to print out the files in a directory and its subdirectories:


find directory -print

After learning about the find command, many new users quickly implement an alias or function as a replacement for locate:


find / -print | grep $1

Page 360

Generally, this is a bad idea because most systems may have network drives mounted, and find will end up trying to access them, causing not only the local machine to slow down, but also remote machines. The correct way to get output like locate from find is the following:


find directories -name name -print

For example, use this line to find all makefiles in /usr/src/:


find /usr/src -name "[mM]akefile" -print

The -name option accepts all shell metacharacters. An alternative to the preceding method for finding all files named Makefile or makefile is to use the case-insensitive -iname option instead of -name. For the truly adventurous, find also supports a -regex option.

In addition to specifying which filenames to find, find can be told to look at files of a specific size, type, owner, or permissions.

To find a file by size, the following option is used:


-size n[bckw]

where n is the size and the letters stand for

b 512-byte blocks (default)
c Bytes
k Kilobytes (1024 bytes)
w 2-byte words

For example, to find all files in /usr over 100KB, use


find /usr -size 100k

To find by files by type, the following option is used:

-

type x

where x is one of the following letters:

b Block (buffered) special
c Character (unbuffered) special
d Directory
p Named pipe (FIFO)
f Regular file
l Symbolic link
s Socket

Page 361

Therefore, to find all the symbolic links in /tmp, use the following:


find /tmp -type l

In addition to simply printing out the filename, find can be told to print out file information by specifying the -ls option. For example,


find /var -name "log" -ls

produces the following output:


42842 1 drwxr-xr-x 2 root root 1024 Jul 17 14:29 /var/log/httpd

157168 1 -rw-r--r-- 1 root nobody 4 Aug 14 17:44 /var/run/httpd.pid

The output is similar in form to the output from ls -il.

The last option of interest for find is the -exec option, which allows for the execution of a command on each filename that matches the previous criteria. The basic syntax of the -exec option is


-exec [command [options]] `{}' `;'

The -exec option uses the string `{}' and replaces it with the name of the current file that was matched. The `;' string is used to tell find where the end of the executed command is. For example, the following makes a list of all the files that contain the word foo in the Linux source files:


find /usr/src/linux -name "*.c" -exec grep -l foo `{}' `;'

Note that the preceding command should appear all on one line.

xargs

One of the biggest limitations of the -exec command is that it can only run the specified command on one file at a time. The xargs command solves this problem. It enables the user to run a single command on many files at one time. In general, it is much faster to run one command on many files because this cuts down on the number of commands that need to be started. Here's how to modify the preceding example to count the number of files with foo in them:


find /usr/src/linux -name "*.c" -exec grep -l foo `{}' `;' | wc -l

Note that this command, also, should appear all on one line.

In my version of the sources (780 files), there were 27 files with the word foo in them, and it took about 44 seconds to find that out.

Now let's modify it to run with xargs. First, you need to replace the -exec grep foo `{}' `;' part with an xargs so to avoid having to start up new greps for each file. The basic syntax for xargs is


xargs [options] [command [options]]

Previous | Table of Contents | Next