Classic Shell Scripting - Arnold Robbins [151]
1024+0 records in
2048+0 records out
0.000u 0.660s 0:00.66 100.0% 0+0k 0+0io 86pf+0w
The more that /dev/random is read, the slower it responds. We experimented with these devices on several systems, and found that it could take a day or more to extract 10MB from /dev/random, and that /dev/urandom can produce that much in less than three seconds on our fastest systems.
These pseudodevices provide an alternative to mktemp for generating hard-to-guess temporary filenames:
$ TMPFILE=/tmp/secret.$(cat /dev/urandom | od -x | tr -d ' ' | head -n 1)
$ echo $TMPFILE
Show the random filename
/tmp/secret.00000003024d462705664c043c04410e570492e
Here, we read a binary byte stream from /dev/urandom, convert it to hexadecimal with od, strip spaces with tr, and stop after collecting one line. Since od converts 16 bytes per output line, this gives us a sample of 16 8 = 128 random bits for the suffix, or 2128 (about 3.40 1038) possible suffixes. If that filename is created in a directory that is listable only by its owner, there is effectively no chance of its being guessed by an attacker.
* * *
[2] Available at ftp://ftp.mktemp.org/pub/mktemp/.
[3] Available at the following: http://www.cosy.sbg.ac.at/~andi/SUNrand/pkg/random-0.7a.tar.gz and http://sunrpms.maraudingpirates.org/HowTo.html. Sun offers patches (10675[456]-01) to the SUNWski package to provide them on older Solaris releases; search for them at http://sunsolve.sun.com/.
[4] By Peter Gutmann, Springer-Verlag, 2004, ISBN 0-387-95387-6.
Finding Files
Shell pattern matching is not powerful enough to match files recursively through an entire file tree, and ls and stat provide no way to select files other than by shell patterns. Fortunately, Unix provides some other tools that go beyond those commands.
Finding Files Quickly
locate , first introduced in Berkeley Unix, was reimplemented for the GNU findutils package.[5] locate uses a compressed database of all of the filenames in the filesystem to quickly find filenames that match shell-like wildcard patterns, without having to search a possibly huge directory tree. The database is created by updatedb in a suitably privileged job, usually run nightly via cron. locate can be invaluable for users, allowing them to answer questions like, Where does the system manager store the gcc distribution?:
$ locate gcc-3.3.tar
Find the gcc-3.3 release
/home/gnu/src/gcc/gcc-3.3.tar-lst
/home/gnu/src/gcc/gcc-3.3.tar.gz
In the absence of wildcard patterns, locate reports files that contain the argument as a substring; here, two files matched.
Because locate's output can be voluminous, it is often piped into a pager, such as less, or a search filter, such as grep:
$ locate gcc-3.3 | fgrep .tar.gz
Find gcc-3.3, but report only its distribution archives
/home/gnu/src/gcc/gcc-3.3.tar.gz
Wildcard patterns must be protected from shell expansion so that locate can handle them itself:
$ locate '*gcc-3.3*.tar*'
Find gcc-3.3 using wildcard matching inside locate
...
/home/gnu/src/gcc/gcc-3.3.tar.gz
/home/gnu/src/gcc/gcc-3.3.1.tar.gz
/home/gnu/src/gcc/gcc-3.3.2.tar.gz
/home/gnu/src/gcc/gcc-3.3.3.tar.gz
...
* * *
Tip
locate may not be suitable for all sites because it reveals filenames that users might have expected to be invisible by virtue of strict directory permissions. If this is of concern, simply arrange for updatedb to be run as an unprivileged user: then no filenames are exposed that could not be found by any user by other legitimate means. Better, use the secure locate package, slocate;[6] it also stores file protections and ownership in the database, and only shows filenames that users have access to.
* * *
updatedb has options to support creation of locate databases for selected portions of the filesystem, such as a user's home-directory tree, so locate can readily be used for personal file lookups.
Finding Where Commands Are Stored
Occasionally, you may want to know the filesystem location of a command that you invoke without a path. The Bourne-shell