- Feb 7, 2003
Working with Files and Directories
Although various graphical interfaces are available for FreeBSD that provide Windows Explorerlike interfaces for managing files and directories, it is sometimes very useful to be able to manipulate files and directories from the command line. If you have never worked with a command line before, this might seem like a step backward in history to you. But actually, for many tasks, the command line can be much more powerful and quicker to work with than a graphical user interfaceespecially for doing things that involve manipulating a large number of similar files.
If you have worked with the command line in Windows, or with DOS, you will find that the FreeBSD command line is quite similar for most things, although some command names are different. If you have not worked a command line before, this section provides a gentle introduction to it.
Even if you are an experienced Windows command-line user, you should at least skim this section because some commands will not behave the way you would expect them to behave in DOS. Particularly important is the section on FreeBSD wildcards, which behave quite differently from DOS wildcards.
Wildcards that do absolutely nothing in DOS could potentially delete every file in a directory in FreeBSD!
The following sections go through some of the basic file and directory manipulation commands. Because most people learn best by actually doing rather than just reading, I suggest that you follow along by logging in to your FreeBSD system using the user you created during the installation and try these commands yourself.
Creating and Deleting Directories
The FreeBSD command for creating a new directory is mkdir. It is short for make directory. In its most basic form, simply follow the command name with the name of the directory that you want to create. For example,
bash$ mkdir mydir bash$
This command creates a new directory in the current directory called mydir.
Rules for Directory Names
FreeBSD has very few rules for directory names. However, for the sake of making things easier to work with, there are certain conventions that I suggest you follow. Note that all these rules apply to filenames as well.
It is possible to create directory names that contain spaces, but in order to do so, you need to use quotation marks around the entire directory name. FreeBSD interprets a space as an argument separator for the command. In other words, if you type the command mkdir my dir, FreeBSD will interpret the space between my and dir as an argument separator. The result is that the command will create two new directories one named my and the other named dir. For the command to have the desired effect of creating a directory called "my dir", you need to type it like this:
mkdir "my dir"
Because typing quotation marks around directory names is inconvenient and also error prone, I suggest that you avoid using directory names with spaces. One common solution is to use the underscore character instead of a space (for example, "my_dir"). This avoids the potential error of using spaces in directory names.
Directory names that contain spaces also pose a potential danger for making mistakes that can have unintended results. For example, suppose that you have a directory called documents from work, another directory just called documents, and a third one called work. You want to delete the directory called documents from work. As I said before, FreeBSD interprets a space as an argument separator unless it is quoted. The command to remove a directory is rmdir. If you forget to quote and type the command rmdir documents from work, FreeBSD will attempt to remove three directories named documents, from, and work. In this case, failure to quote will have disastrous results because this command will delete the documents directory and the work directory, while leaving the documents from work directory untouchednot what you intended to happen. Using the underscore character instead of the space avoids the danger of this happening.
Also, you cannot begin a directory or filename with a dash character (-) because FreeBSD interprets the dash to indicate that what follows is a parameter that modifies the behavior of the given command. You can have dashes in the middle of your filenames and directory names, however.
To delete the directory you just created, use the rmdir command. For example,
bash$ rmdir mydir bash$
Note that rmdir can only remove directories that are empty. If there are any files or subdirectories within the directory, you will get the error message directory is not empty. Later in this hour, we will look at a command that can remove directories that are not empty.
Note that the rmdir command does not ask for confirmation before it goes to work. FreeBSD assumes that you know what you are doing and by default, commands almost never ask for confirmation before they go to workeven if you have told them to do something extremely destructive. If you are not sure what you are doing, there is a command line option to use with most commands. The option is i. The i is short for interactive. This causes the command to ask you for confirmation before it actually does anything. This option can be very useful when you are not entirely sure that the command you are giving FreeBSD will have the intended effect. If it turns out that the command is going to do something other than what you intended, the i option will let you know about it and give you the opportunity to bail out before it is too late.
Assuming that you are following along and you issued the preceding rmdir command, go ahead and re-create the directory using the mkdir command again because we will use it in the next section.
Listing Directory Contents
The ls command is used to list the contents of directories. Here is some sample output from the ls command:
bash$ ls Mail projects proposal-draft program1 tyfbsd mail program1.c bash$
The main problem with this listing is that it gives you virtually no information about what kinds of things actually exist in the directory other than their names. But there is no way to tell whether the entry belongs to a file, subdirectory, and so on. Because of this, the ls command provides several options that can be used to get it to display more information on each entry. For example, the F entry causes ls to give us more information about the type of each entry in the list:
bash$ Mail/ projects/ proposal-draft program1* tyfbsd@ mail/ program.c bash$
The symbols behind some of the entries in the preceding listing tell us what kind of entry it is. Here is what they mean:
/: The item is a directory.
*: The item is an executable program or script.
@: The item is a symbolic link to another location. This is similar to a shortcut in Windows.
Unlike Windows, executable files in FreeBSD are not required to have a .EXE or .COM extension. We will look at how FreeBSD determines whether a file should be executable or not later on.
In FreeBSD, files that begin with a leading period (.) will be hidden in the normal directory listing. Files beginning with periods are normally configuration files that control behavior of programs and your working environment. Because these files are rarely accessed, FreeBSD hides them in the normal directory listing to avoid cluttering up the listing with entries that are irrelevant most of the time. If you want to see the hidden files, use the a option with the ls command. The a is short for all:
bash$ ls a . .forward .mailrc .profile Mail .. .hushlogin .project tyfbsd .addressbook .sh-history .cshrc .mail_aliases bash$
It's not important that you know what all these files mean at this point, but you might be able to guess at the meanings from some of the names. For example, files here contain your user profile, control how your email should be delivered and whether it should be forwarded, and so on.
Two entries here deserve special mention. Those are the entries . and ... The single period represents the current directory, and the double period represents the parent directory of this directorythat is, the directory that this directory is a subdirectory of. With the exception of the root directory (/), all directories have a parent directory.
Another useful option to ls is the l option. l is short for long, and this gives you many more details about each entry in the list. For example,
bash$ ls l drwx 2 murban research 512 Feb 15 22:21 Mail lrwxr-wr-w 1 murban research 15 Mar 20 06:55 tyfbsd -> /home/murban/documents/books/tyfbsd -rw-rr 1 murban research 782 Mar 15 01:22 proposal-draft -rwx 1 murban research 15200 Mar 15 02:21 program bash$
I'm not going to cover all the information given in this list at this point, but I will cover some of the more important information.
The first set of entries lists the type of the entry and its permissions. The first entry, Mail, starts with d, which means that the entry corresponds to a directory. The next nine spaces correspond to the permissions. There are three spaces for the owner of the file, three spaces for the group of the file, and three spaces for other, which includes everyone else. In this case, the owner has read, write, and execute permissions on this directory (rwx). The group and the user have no permissions. Who are the owner and group? Those are indicated by the third and fourth entries. In this case, the owner is murban and the group is research. (My group membership is research). In this case, this means that murban can do whatever he wants with this directory (read, write, execute), but no one else can do anything. I will explain permissions in more detail in a later hour.
The next entry after research indicates the size of the entry in bytes. After that comes the date and time that the entry was last modified. The last entry is, of course, the name of the file.
The second line deserves special mention. An entry that looks like this
lrwxr-wr-w 1 murban research 15 Mar 20 06:55 tyfbsd -> /home/murban/documents/books/tyfbsd
indicates a symbolic link. As mentioned previously, symbolic links are like shortcuts in Windows. In this case, the entry tyfbsd is actually a shortcut to the directory /home/murban/documents/books/tyfbsd. The symbolic link allows me to get to this directory by just using tyfbsd instead of the much longer path.
To move to a different directory, use the command cd, which is short for change directory. For example, to change to the directory tyfbsd, which is a subdirectory off the current directory, you would use the command cd tyfbsd. This is called a relative path. A relative path means that the directory given to the cd command is relative to the directory you are currently in. In other words, the command is relative to the directory you are currently in, and the tyfbsd directory is a subdirectory of the current directory. The alternative is an absolute path. An absolute path always begins at the root directory. Recall that the root directory is represented by / and is the top-level directory in the system. An example of using cd with an absolute directory would be cd /tyfbsd. This would change to a directory called tyfbsd located in the root directory.
You might recall from the previous section that the double period (..) represents the parent directory of the current directory. Because of this, you can use the double period to move up one directory level to the parent of the directory you are currently in. The command to do this would be cd ... If you want to move up two directory levels, you can use cd ../.., and so on. If you want to move to a directory called my_stuffwhich is located in the parent directory of the current directoryyou could use the command cd ../my_stuff.
If you get lost in the FreeBSD directory structure, you can instantly return to your home directory by typing cd followed by pressing the Enter key. The cd command with no arguments will always take you back to your home directory no matter where you currently are in the directory tree.
The pwd Command
If you can't remember what directory you are currently in, the pwd command will list it for you. pwd stands for print working directory. There is a way to make the current working directory a part of your shell prompt so that the prompt always shows you what directory you are currently in. We will look at how to do this in Hour 5, "Advanced UNIX Shell Use."
There are several ways to create an empty file in FreeBSD. For our purposes right now, we are going to use the touch command. If you are not already in it, change to the directory we created earlier called mydir using the cd command discussed previously. Now enter the command touch myfile. This will simply create an empty file called myfile in the current directory. Of course, empty files are not very useful, but this will allow you to look at some basic file manipulation commands.
The tilde character, ~, is shorthand for your home directory. It can be used anywhere that you want to refer to your home directory. For example, cd ~/documents will take you to the documents directory located within your home directory no matter where you currently are in the directory tree.
The command to move a file from one place to another is mv. Try the following command:
mv myfile myfile1
This command will simply move myfile to a new file called myfile1. Of course, you can also think of this as simply renaming the file. However, the behavior of mv will depend on myfile1. If myfile1 does not already exist as an entry in the directory list, the behavior will be as previously mentioned. myfile will simply be renamed to myfile1. If myfile1 already exists in the directory and it is an existing file, myfile will overwrite myfile1. Note that FreeBSD will not ask for confirmation before overwriting the existing file. So once again, you might want to use the i option to mv if you aren't completely sure of what you are doing. As with the rmdir command mentioned earlier, the i will make the command interactive, so it will prompt before doing anything.
If myfile1 already exists in the current directory and is a subdirectory, the command will move myfile into the subdirectory myfile1 and myfile will keep its existing name. Thus, the result will be that the file is now located at myfile1/myfile. Note that if the file myfile already exists in the subdirectory myfile1, FreeBSD will overwrite the existing fileonce again, without asking for confirmation first.
The command to copy a file from one location to another is cp. It behaves very much like the mv command except that it creates a copy of the file instead of moving it. Like the mv command, cp will create a copy of the file under a new name if the second name given to the cp command doesn't already exist. If the second name given is a directory, cp will make a copy of the file in the new directory, and the new file will maintain its original name. Also, like the mv command, cp will overwrite an already existing file with the same name without asking permission first. So once again, it might be a good idea to use the i option if you are not 100% sure what you are doing.
The cp command can also be used to copy directories. By default, however, it will not go more than one level deep. If you want to recursively copy a directory and all of its subdirectories (in other words, you want to copy a directory and everything inside it), you can use the R option to the cp command. Once again, you might also want to use i to prevent cp from accidentally overwriting any files you didn't intend to overwrite.
You can get yourself in trouble with the R option to cp. For example, a command such as cp R ./* ./old will attempt to recursively copy everything in the current directory to a new directory called old, which is also located in the current directory. (I haven't introduced wildcards yet, but basically, * is a wildcard that means everything.) The problem with this is that the directory old will also be recursively copied into itself. The result is a recursive loop that will quickly fill up all the available space on the hard disk. Watch out for situations like this.
The rm command is used to delete files. In its basic form, simply follow the rm command with the name of the file you want to delete. For example, rm myfile will delete myfile in the current directory. The rm command can also be used to delete a directory and everything underneath it by using the r option. For example, rm r mydir will remove all subdirectories and files located in mydir and then will remove mydir. Of course, it is possible to do a lot of damage with the r option because once again, FreeBSD will not ask for confirmation before it carries out the command, so always double-check the command line before you press Enter to make sure that you are removing the right directory. Also always be sure that there is nothing you want to keep anywhere in any directory beneath the one you are deleting. If you are not totally sure, use the i option along with the r option. This will cause FreeBSD to ask you to confirm each thing it is going to delete.
Like their card game counterparts, wildcards are used to match any character or sequence of characters. They can be used for such things as moving multiple files or deleting multiple files. There are many ways to write wildcards in FreeBSD, but here we will only look at the two most basic ways. These ways are the question mark (?) and the asterisk (*). The question mark stands for any single character, whereas the asterisk stands for zero or more characters. If you aren't familiar with the command line, this might seem as clear as mud at this point, so I will go through a few examples to make it more clear.
Suppose that we have the following list of files in a directory:
project1 project2 project3 myproject proposal.draft
The command rm project? will remove the files project1, project2, and project3 because the question mark can stand for any single character. So in this case, the 1, the 2, and the 3 will be matched by the wildcard.
The command rm proj* would have the same effect as the previous command because it will match all files starting with "proj" and containing zero or more unknown characters following "proj."
The command rm pro* would also remove the same three files, but in addition, it would remove the proposal.draft file because it also begins with the sequence pro. This is an example in which wildcards could get you in trouble. The lesson is that you should always use the maximum number of characters you can before the * wildcard. Don't take unnecessary shortcuts just to avoid typing because as this example shows, you could end up deleting a file you didn't intend to delete.
As you might have guessed already, the command rm * will remove every file in the directory. Sometimes this might be your intention, but it also means that you need to double-check the command line whenever you are using the * wildcard. A simple typo can be disastrous. For example, suppose that you want to remove all the files beginning with "proj" but instead of typing rm proj*, you accidentally type rm proj *. Remember that FreeBSD interprets the space as an argument separator. So a typo as simple as putting a space between proj and the asterisk changes this command to delete the file proj and then delete every other file in the directory! As you can see, it is always very important to double-check your command line when working with wildcards because even simple typos can cause disaster.
One way you can see which files or directories will be affected by the wildcard you are intending to use is to use it with the ls command first. This will simply list all the entries that match the given wildcard.
DOS users beware! Wildcards in FreeBSD can behave much differently than you are used to. One major reason for this is that FreeBSD does not give any special meaning to a period in a filename as DOS does. As far as FreeBSD is concerned, the period is just another character. The result is that the command rm * will delete every file in the current directory in FreeBSD, whereas in DOS, the same command would usually have little to no effect.