|< Day Day Up >|
Managing Files and Directories
Having mastered navigating about the filesystem, it's now time to learn how to interact with some of the files. We'll start with basic file manipulation commands that do things such as rename files and make copies of them, and then cover more complicated things such as finding files, extracting portions of their contents, and archiving them.
As mentioned previously, Unix commands tend to be small, single-function commands that can be combined to form more complex functionality. You see this demonstrated by many commands in this chapter; their functionality might seem oddly limited if you're not used to the Unix command philosophy. By the time you're finished with this chapter, however, you should begin to see how the commands could be fit together, and you should be able to abstract what you learn here to most Unix commands.
Moving and Renaming Files: mv
If you're a longtime Macintosh user, you are probably familiar with the notion of moving files about by way of the Macintosh's drag-and-drop formalism. Unix and its command line might not seem like a particularly appealing way to deal with moving files having to type the names and paths to directories can't possibly be much fun! There's no denying that there are certain tasks for which the drag-and-drop way works much better than the command line. But, although you might not have thought about it, there are also situations in which drag-and-drop makes your life much more difficult. Interestingly, these are frequently situations in which the command line works particularly well; for example, when a folder contains many files of the same type, and you're interested in using a number of them that are related by name rather than by icon position. In a situation such as this, rearranging things in the Finder, or Shift-clicking your way through the list of files to pick the ones you want, is usually less efficient than choosing them from the command line by using a shell filename wildcard. Similarly, it's frequently faster to type a filename, if you know it, than to scroll around in a Finder window looking for the file. For these reasons, as well as conveniences that really become apparent only from experience rather than explanation, the command line makes for a useful complement to the Finder for certain operations.
Renaming files in Unix is accomplished with the mv (move) command. It might seem odd at first that renaming a file is accomplished by moving it, but it makes sense in the Unix philosophy of accomplishing things in simple, abstract ways. Why create two commands that do essentially the same thing, when one command can do both with the same syntax, the same way? To rename a file from one name to another, simply use mv <oldfilename> <newfilename>. For example, if you're in a directory with a file named mynewfile, and you want to rename it as myoldfile, you might do something like this:
brezup:nermal Documents $ ls lynx lynx.cfg mynewfile test brezup:nermal Documents $ mv mynewfile myoldfile brezup:nermal Documents $ ls lynx lynx.cfg myoldfile test
Remember that most commands can take absolute paths or relative paths to files? Well, being in the same directory and using just the filenames is using the relative paths. On the other hand, you can accomplish the same thing using the absolute paths to the files. Starting from where we left off in the previous example, this might look like the following:
brezup:nermal Documents $ pwd /Users/nermal/Documents brezup:nermal Documents $ mv /Users/nermal/Documents/myoldfile/Users/nermal/Documents /myevenolderfile brezup:nermal Documents $ ls lynx lynx.cfg myevenolderfile test
Because you can do that, why should you need to be in the same directory as the files at all? As a matter of fact, because you can specify the full paths to the files, what is to stop you from changing something other than the filename when you use the mv command? What if you decide to change one of the directories in the full path while you're at it? For example, let's look at what happens if you move a file from the Documents directory at the same time that you change its name:
brezup:nermal Documents $ cd ~ brezup:nermal nermal $ ls Desktop Network Trash Folder chown-output Documents Pictures myfile Library Public output-sample6 Movies Sites su-output Music TheVolumeSettingsFolder typescripts brezup:nermal nermal $ ls Documents lynx lynx.cfg myevenolderfile test brezup:nermal nermal $ mv /Users/nermal/Documents/myevenolderfile/Users/nermal/Public /myolderfile brezup:nermal nermal $ ls Documents/ lynx lynx.cfg test brezup:nermal nermal $ ls Public/ Drop Box myolderfile
The end result is that Unix's abstraction of file access and naming causes the full path to the file to be, essentially, the full proper name of the file. "Renaming" it using the mv command can result in a change to any part of that name, including the parts that indicate the directory in which the file exists. See? Nothing odd about using the same syntax to rename files as used to move them about at all.
Table 10.6 lists the syntax and primary options for mv.
Creating Directories: mkdir
The mkdir command is used to create directories. The usual syntax is simple, being most commonly used as
mkdir <new directory name>
This creates a new directory named <new directory name> in the current directory. Full and relative paths are allowed to the new directory being specified. If the path to the directory that you are attempting to create does not completely exist, mkdir does not (by default) create the entire directory structure. For example, if you want to create /usr/local/tmp/testing/morefiles/, and the directory /usr/local/tmp/testing/ does not exist, you either have to create it before you can create /usr/local/tmp/testing/morefiles/ or use the -p option to mkdir. The -p option causes mkdir to create the entire path (if any of it's missing), as well as the final directory. This can be both a great convenience and a real nuisance. If you're an accurate typist, you don't need to issue multiple mkdir commands to create a deep directory hierarchy. On the other hand, because it creates directories that don't exist, a typo in a higher-level directory name just causes the mistyped name to be created, making typing errors annoyingly invisible when they're committed. Users new to Unix might like to add the -v flag as well so that mkdir reports what it's doing as it goes. Table 10.7 shows the syntax and primary options for mkdir.
Copying Files: cp
The cp (copy) command functions similarly to the mv command, but instead of renaming a file between two locations, the cp command creates a duplicate of the file. The syntax is also similar, copying a file from one location to another or copying a number of files into a directory.
If our user nermal wants to copy some images to the /Users/shared directory so that all users can conveniently find the images without having to remember which user has the images, she can copy them with the cp command to the desired location.
Because nermal is new to Unix, she first decides to double-check that the images are located where she thinks they ought to be with the following:
brezup:nermal Documents $ ls -l Public/Drop\ Box/shar*tiff -rw-r--r-- 1 nermal staff 872714 Apr 16 16:17 Public/Drop Box/sharing-1.tiff -rw-r--r-- 1 nermal staff 873174 Apr 16 16:17 Public/Drop Box/sharing-2.tiff
Then she actually copies them and verifies that they copied:
brezup:nermal Documents $ cp Public/Drop\ Box/shar*tiff /Users/shared/ brezup:nermal Documents $ ls -l /Users/shared total 3424 -rw-r--r-- 1 nermal wheel 872714 Apr 23 11:08 sharing-1.tiff -rw-r--r-- 1 nermal wheel 873174 Apr 23 11:08 sharing-2.tiff
She could have copied each file individually, but cp can fortunately take multiple files in its arguments, so she can use shar*tiff to refer to both files. Note that the copies in the /Users/shared directory show the date that they were copied, rather than the original date. If everyone knows that the images from April 16 are the ones they need to use, they might be confused by the April 23 date. nermal could remove this confusion by specifying the -p option, which preserves as much as possible of the original modification time, user information, and so on:
brezup:nermal Documents $ cp -p Public/Drop\ Box/shar*tiff /Users/shared/ brezup:nermal Documents $ ls -l /Users/shared total 3424 -rw-r--r-- 1 nermal staff 872714 Apr 16 16:17 sharing-1.tiff -rw-r--r-- 1 nermal staff 873174 Apr 16 16:17 sharing-2.tiff
Note the use of the \character to escape the space in the folder named Drop Box so that the shell doesn't interpret Public/Drop as one argument and Box/shar*.tiff as another.
If user joray has promised nermal some test data in a subdirectory named tests-for-nermal in joray's home directory, nermal can recursively copy the test directory to her own home directory as follows:
brezup:nermal Documents $ cp -R ~joray/tests-for-nermal ./
A check shows that a directory was indeed copied:
brezup:nermal Documents $ ls -ld tests-for-nermal drwxr-xr-x 9 nermal staff 262 Apr 23 11:29 tests-for-nermal
Not only that, but there was a directory under that directory, and cp copied it:
brezup:nermal Documents $ ls -l tests-for-nermal total 48 -rw-r--r-- 1 nermal staff 15 Apr 23 11:29 broken -rw-r--r-- 1 nermal staff 20 Apr 23 11:29 broken-again -rw-r--r-- 1 nermal staff 23 Apr 23 11:29 fix -rw-r--r-- 1 nermal staff 17 Apr 23 11:29 fix2 -rw-r--r-- 1 nermal staff 848 Apr 23 11:29 test drwxr-xr-x 4 nermal staff 92 Apr 23 11:29 test-data -rw-r--r-- 1 nermal staff 848 Apr 23 11:29 test2
You have seen just some of what you can do with cp. The complete syntax and options for cp are shown in Table 10.8, the command documentation table.
Creating Symbolic Links: ln
Sometimes it is useful to link an alternative name with a particular file or directory, or make a file appear to be in two places at once, without actually creating a duplicate of that item. You're already used to this idea from the Finder notion of aliases. At the command line, the same thing can be done with the ln command. It is especially useful for administrative purposes, but even a regular user might need to link a filename or directory name to some other particular name. The best way to do this is to use a symbolic link. The simplest syntax for making a symbolic link is
ln -s <source> <target>
Because the syntax is similar to the basic cp syntax, you won't have much trouble remembering it.
You might be wondering just what sort of use you might have for symbolic links. An instance in which you might use a symbolic link is for your website. Suppose that you are using a web editing suite that uses home.html for the default name for the main page of your website. Suppose, however, that your web server is set to read only files named index.html as the default page for a directory. If you use home.html, you might have to give out something like http://ryoohki.biosci.ohio-state.edu/~nermal/home.html as your URL. If, on the other hand, your home.html file were really called index.html, you could give out a slightly shorter URL instead: http://ryoohki.biosci.ohio-state.edu/~nermal/.
What could you do to get an index.html file in your directory if your web editing suite won't create one? And how could you keep it conveniently updated to match home.html? Well, as you just saw, you could copy home.html to index.html. But the next time you edited home.html, you would then have to remember to copy home.html to index.html when you were finished. Although you might be good about remembering to do that, you undoubtedly will eventually forget, probably when it matters most. If you simply link index.html to home.html, every time you update home.html, you don't have to remember to do anything else! To create the symbolic link, do the following:
brezup:nermal public_html $ ln -s home.html index.html
A quick check shows us that index.html is now a link to home.html.
brezup:nermal public_html $ ls -l total 16 -rw-r--r-- 1 nermal staff 52 Apr 23 11:56 home.html lrwxr-xr-x 1 nermal staff 9 Apr 23 11:56 index.html -> home.html
A common administrative use for symbolic links is to move a directory from one partition to another, while leaving the path that a user would use to get to the directory the same. This makes the administrator's change transparent to the user for most purposes. An example of this follows. On this machine, obup, the /usr partition was getting full, so the local directory of /usr/local was moved to a partition named /home. After the directory was moved, the /usr/local directory was replaced with a symbolic link that points to /home/local.
obup:joray / $ ls -l /usr/local lrwxrwxrwx 1 root other 11 Mar 20 1997 /usr/local -> /home/local
If a user changes to the /usr/local directory and then checks his location with pwd, he finds the following:
obup:joray / $ cd /usr/local obup:joray local $ pwd /home/local
So, as the user might have grown to expect, he can still cd to /usr/local but without having to know any of the "administrivia" behind its actual location.
Table 10.9 shows the syntax and primary options for ln.
Changing Modification Times and Creating Empty Files: touch
The touch command is used to update the last-modified time for a file. This command also has the side effect of creating a new, empty file if the file that you attempt to touch does not exist.
Neither of these functionalities probably sounds particularly interesting at the outset, but, in fact, they both have good uses. For example, most archiving and backup software is frequently configured to back up only files that have changed since the last backup. Using touch on a file makes it appear to have been changed, which results in it being flagged for backup. Because the touch command can be quickly applied from the command line to a large number of files, it enables you to conveniently force some files to be backed up without having to open and resave each in its parent applications.
Creating empty files doesn't have much use at the command line but turns out to be useful when you start writing programs in the shell scripting language (see Chapter 15). In this case, multiple simultaneously running scripts can be made to talk to each other by the creation of empty files known as flag files essentially the electronic equivalent of a script raising a flag to tell another script that something has happened.
To create a new (empty) file with touch, or to update the modification date of the file to the current time, the syntax for the touch command is simply
touch <filename to modify>
The touch command can actually update files to have any modification time that you want, although the preceding is by far the most common usage. Table 10.10 shows the syntax and options for touch.
Removing Files and Directories: rm, rmdir
Removing files and removing directories with Unix are fairly straightforward tasks, so you need to know only two commands to accomplish them.
Now that you have filled up your directory with many files, it is time to learn how to clean it up a bit. You can remove a file with rm. Our user nermal has decided that her file called myfile is no longer needed. To remove it, she does the following:
brezup:nermal Documents $ ls -l myfile -rw-r--r-- 1 nermal staff 51 Apr 12 15:11 myfile brezup:nermal Documents $ rm myfile remove myfile? Y
As you notice in this example, rm prompts for confirmation before removing the file. Your system might not be configured to make rm prompt you for the removal of files. You can cause rm to ask for confirmation by aliasing rm to rm -i. Aliasing is a technique covered in more depth in Chapter 15. For now, you want to add either the first or second lines that follow to the .bashrc file or .cshrc file in your home directory (the first if you're using bash, and the second if you're using tcsh). Alternatively, you could add them to /etc/bashrc or /etc/csh.cshrc to make the change for all users of your system.
alias rm='rm -i'
alias rm 'rm -i'
We highly recommend that you follow these instructions to make your rm command interactive at the first possible opportunity. After you're a seasoned Unix user, you're welcome to run with rm in noninteractive mode by default; but until you've been sure that you're ready a long, long time, it's probably safest to have it operate interactively by default.
Our user nermal has also decided that she is finished with the data that she copied from user joray's directory and that she wants to remove the entire directory. The easiest way to do this is to force rm to recursively remove the directory, using options -r for recursive, and -f to override the interactive mode she has enabled by default, as shown here:
brezup:nermal Documents $ ls -ld tests-for-nermal drwxr-xr-x 9 nermal staff 262 Apr 23 11:29 tests-for-nermal brezup:nermal Documents $ rm -rf tests-for-nermal [localhost:~] nermal% ls -ld tests-for-nermal ls: tests-for-nermal: No such file or directory
Removing a directory and all its contents using the recursive and force options to rm is easy, but it is also silent and very fast. Remember to use those options only when you really mean it. Double-check everything before you run it. As you can see in the example, there is no recourse if you type the wrong thing.
Table 10.11 shows the syntax and primary options for rm.
There is also a command available for removing directories: rmdir. It is useful only for removing empty directories, but this is also a valuable limitation on its capabilities. It lets you rmdir rather indiscriminately, and know for certain that it will delete only unoccupied directories, and never any real files. Table 10.12 shows its complete syntax and options.
|< Day Day Up >|