Home Button

A Mac User's Guide to the Unix Command Line, Part 3


About

Meetings

Articles

Links

Contact

Join

Forums

by Kirk McElhearn <kirk@mcelhearn.com>

First Steps with the Command Line

When Apple announced the release of Mac OS X, many Mac users were stunned: here was a new operating system based on the venerable Unix, which, they feared, would call into question the Mac's legendary ease-of-use. Mac users have long been staunch supporters of point-and-click interfaces, and Unix, or so they thought, was the exact opposite. Since Mac OS X presents a graphical user interface atop its Unix foundations, there is no need for worry - seasoned Mac users can feel right at home (after some adjustments) with the new interface, and not even know about the Unix underpinnings that make Mac OS X run.

Not everyone was apprehensive, however. Many Mac users, especially those who have worked in large businesses or educational institutions, have for years used Unix variants, or flavors, such as one of the many Linux distributions. They were delighted to discover that they could use their Macs and still wield the power of Unix (specifically, FreeBSD 4.4, one of the oldest and most stable versions of Unix). They can have access to the myriad command-line tools available for Unix and the powerful programs provided as standard equipment in Mac OS X, such as the Apache Web server, numerous network utilities, a compiler and more. And they can still benefit from Apple's easy-to-use graphical user interface.

Unix is reputed to be complex - its cryptic commands are said to offer a steep learning curve and not be accessible to "the rest of us." While this can be true - some Unix commands are like a foreign language - the command line can also be simple, useful, and powerful.

The goal of this article (the first in an occasional series to be published in TidBITS over the next year) is to present a brief example of how you can use Mac OS X's command-line interpreter, the Terminal application, to run a few simple commands, and see exactly how they work. You will discover, if you follow this easy tutorial, that Unix doesn't bite.

Opening Terminal
Terminal is the program Apple includes in Mac OS X to provide the interface between the commands you type and the operating system. Terminal is a "dumb" program - it does little more than pass information on to a shell (another program that interprets these commands) and display the results of these commands.

Start by opening Terminal, which is located in the Utilities folder of your Applications folder (or, to use the Unix convention, /Applications/Utilities). Double-click the Terminal icon. The Terminal window displays, showing something like this:

Last login: Mon Nov 25 16:03:03 on ttyp1
Welcome to Darwin!
[Walden:~] kirk%

This text tells you several things:

  • The first line shows the date and time of the last login, followed by the terminal device ("ttyp1") being used.
  • The second line is the Message of the Day. The default message of the day for Mac OS X (as of version 10.2) is "Welcome to Darwin!", Darwin being the name of the Mac implementation of BSD Unix. (Like most things in Unix, you can easily change this text; we'll see how to do that in a later article.)
  • The third line is the prompt. It first shows the localhost, or computer, that is being used: in this case, my Mac's name Walden. The current directory, or folder, is shown after the colon following the localhost name. When you open a new Terminal window, the current directory is by default your Home folder, represented by the ~ shortcut. The final part of the prompt is the short name of the currently logged-in user, kirk. (Obviously, your localhost and user name will look different than mine.)


The prompt indicates that you can type commands. If Terminal is working on a command or displaying certain processes, you don't see a prompt. If this is the case, you can always open a new Terminal window to type commands; you can open an unlimited number of Terminal windows, called sessions, at any time.

Typing Your First Command
Now that we've gotten through the basics, you're ready to type your first command. Let's start with echo, a simple command that displays what follows the command name in the Terminal window.

(Note: in the rest of this article, the commands and text you are to type are shown following the prompt sign, %, but without the localhost name and user name. You don't need to type the prompt text; just type what follows the % sign.)

Type the following:

% echo Hello!

and press Return or Enter. Terminal displays the above line (the prompt and the text you type) as you type it. The echo command writes an argument to the Terminal's standard output; in this case, the Terminal window itself. After you press return, it displays the following line:

Hello!

Your Mac just said hello to you! Now, you can go even further - after all, you don't know to whom it was saying hello. Try this command:

% echo Hello $user!

My Mac says:

Hello kirk!

All commands use a specific syntax - for simple commands, this is often just:

command argument

Arguments are additional information required for some commands; other commands run with no arguments. In the line of text you typed above, the command was "echo" and the argument was the text you wanted Terminal to display.

That was easy, wasn't it? You have just used the command line under Mac OS X. The echo command is certainly simple, but it demonstrates basic command syntax and how Terminal works. (You've probably noticed that, after the above text, Terminal displayed a new prompt on the following line. This is a way of showing, as mentioned above, that the previous command has completed.)

You can now try typing the echo command with other text if you want.

Reading Directory Contents
Let's see some more things you can do with Terminal. In the following series of commands, you will:

 

  • create a new directory,
  • examine the contents of the directory,
  • create a new file,
  • tell your computer to write some text in that file,
  • read the file,
  • then delete the file and directory.


The Terminal prompt shows that you are in your Home (~) directory. Let's see what's in this directory. If you recall from looking at the Finder window, Home contains a few folders. Type the following (the first letter is lowercase L, not the digit 1):

% ls

The ls command lists the contents of a directory. Terminal displays something like the following:

Desktop Library Music Public
Documents Movies Pictures Sites

This is a list of everything in your Home folder (it may be different depending on the contents of your Home folder). However, this list doesn't tell you which of the above items are files or folders. You can find out by typing the following:

% ls -F

Terminal displays this list:

Desktop/ Library/ Music/ Public/
Documents/ Movies/ Pictures/ Sites/

The -F is an option for the ls command; it is also case-sensitive: -F is not the same as -f. Options tell certain commands to do things in a slightly different way. This option tells Terminal to display a slash (/) immediately after each pathname that is a directory, an asterisk (*) after each executable (application), etc. The slashes here show us that these are directories. If any of the above items were files, there would be nothing after their names.

Creating a New Directory
Now, you're going to create a new directory called Test. Type the following:

% mkdir Test

The mkdir command makes new directories. Let's check to make sure this directory has been created by repeating the ls -F command, which shows:

Desktop/ Library/ Music/ Public/ Test/
Documents/ Movies/ Pictures/ Sites/

There it is: Test/, the directory that you just created.

Now we are going to move into that directory, using the cd command:

% cd Test

The cd command changes the current working directory. After running this command, the prompt changes to show that we are now in the Test directory:

[Walden:~/Test] kirk%

As you've already learned, the ~ is a shortcut for your Home directory, and the slash means that the following directory resides inside the Home directory.

Creating a New File
Let's now create a new, empty file inside the Test directory. Type this:

% touch testfile

The touch command is typically used to update file access and modification times, but it can also create a new file; the argument, testfile, is the name we're giving to the file.

Let's check to make sure the file was created. Type:

% ls -F

which should display the following:

testfile

Remember that the -F option for the ls command shows a / following a directory; it shows nothing for files. So we now have a new, empty, file called testfile sitting in the Test directory, just waiting for data to be put into it.

Writing Text to a File
Since our file is doing nothing, we might as well write something to it. How about writing Hello [username]! in this file? To do so, we can use the echo command that we learned above. Type the following:

% echo Hello $user! > testfile

This command tells Terminal to echo the text Hello [username]! to the file called testfile. Let's check and make sure it worked. There are several commands that display the contents of your files; one of them is cat. Type this:

% cat testfile

Terminal should display:

Hello [username]!

But since we only see this in the Terminal window, it doesn't give the same impression as when we open a document window in an application. Let's see what this file looks in a graphical application. Type:

% open .

(Make sure you type open, then a space, then a period.)

This tells the Finder to open the current directory (the . is a shortcut for that) in a new window. You should see a new Finder window, entitled Test, with a file inside it called testfile.

Double-click the testfile icon, which should launch TextEdit and display a window containing the text "Hello [username]!"

Quit TextEdit to close the file, then switch back to Terminal by clicking its icon in the Dock.

Deleting Files and Folders
Now that we have finished our brief demonstration, we need to clean up a bit. We don't need to keep that file and folder, so let's delete them.

Warning! The command line is not without certain risks. Unlike when you work in the Finder, some tasks you carry out are absolute and cannot be undone. The command I am about to present, rm, is very powerful. It removes files permanently and completely instead of just putting them in the Trash. You can't recover files after deleting them with rm, so use it with great care, and always use the -i option, as explained below, so Terminal asks you to confirm deleting each file.

Your prompt should look something like this, showing that you are still inside the Test directory you created earlier:

[Walden:~/Test] kirk%

Type the following:

% rm -i testfile

The rm command removes files and directories, in this case the file testfile. The -i option tells Terminal to run the rm command in interactive mode, asking you to make sure you want to delete the file. Terminal asks:

remove testfile?

Type y for yes, then press Return or Enter and the file is removed. If you wanted to leave it there, you could just type n for no, or press Return.

We should check to make sure the file is gone:

% ls

After typing ls, you should just see a prompt. Terminal doesn't tell you that the directory is empty, but it shows what's in the directory: nothing.

Now, move up into your Home folder. Type:

% cd ..

This is the same cd command that we used earlier to change directories. Here, the command tells the Terminal to go up in the directory hierarchy to the next directory (the .. is a shortcut for the parent directory); in this case, that is your Home directory.

Type ls again to see what's in this directory:

% ls

You should see something like this:

Desktop Library Music Public Test
Documents Movies Pictures Sites

The Test directory is still there, but using rm, it's easy to delete it by typing:

% rm -d -i Test

The -d option tells rm to remove directories. When Terminal displays:

remove Test?

Type y, then press Return or Enter. (If you didn't remove testfile, as explained above, the rm command won't delete the directory because it won't, by default, delete directories that are not empty.)

Make one final check to see if the directory has been deleted.

% ls

Desktop Library Music Public
Documents Movies Pictures Sites

Summing Up
If you worked through this brief demonstration, you successfully typed commands in a Terminal window using the Unix command line. You created a directory (folder), created a file, wrote text to it, then deleted the file and the directory - and all with some very simple commands. Here's a brief summary of the commands you used:

  • echo: displays arguments to the standard output; in the first example, this was the Terminal window, in the second example, it was an empty file.
  • ls: lists the contents of a directory (or folder).
  • mkdir: makes a new directory.
  • cd: switches to a different directory.
  • touch: creates a new, empty file (among other uses).
  • cat: views files (among other uses).
  • open: lets you open files or folders in the Finder.
  • rm: removes files or directories. Use with care!


Although you haven't accomplished anything extraordinary so far, you can see that using Terminal isn't that complicated. All it requires is a bit of time to learn the different commands and their arguments and options. But if you move ahead slowly, learning as you go on, rather than trying to memorize dozens of commands, you'll soon find that you are not only comfortable with the command line, but that you can do things that help you save time and give you much more power.

In the next installment in this series, you'll learn all how to move around in your computer's file system. I'll build on some of the commands presented here (cd, ls, mkdir, and others) and present many new, useful commands.

Navigating the File System

In the first installment of this series, we looked at the basics of using the Terminal to access Mac OS X's Unix core. What's next? Well, when you visit a new place, the first thing you need to learn is how to get from one location to another. So, let's look this time at how you use the Terminal to move around your Mac's file system. (You might want to go back and read the previous article again to refresh your memory before continuing.)

<http://db.tidbits.com/ getbits.acgi? tbart= 07003>

As you are certainly already aware, your files are organized in a hierarchy of directories (the Unix word for folders). When moving around in the Finder, you open folders, which display other folders and files, and you drag, copy and paste files and folders among the windows that the Finder displays. In the Unix world, you navigate among directories using commands, displaying lists of files and directories, and you move, copy and paste files and directories from the command line.

In most cases, you're probably better off using the Finder for your everyday activities. But navigating the file system with the Terminal can have a few advantages:


•It's fast. You can jump from one directory to another in a split-second, as long as you know its path. There's no need to open window after window to get where you want.

•It's informative. While you can access most of the same information from the Finder - such as file permissions - the Terminal displays these details more quickly. For example, you can use the Finder's Get Info window to learn the permissions for an entire folder of files, but you must do so individually for each file. With the Terminal, you can display a list showing permissions for all the files instantly.

• It's complete. You can access invisible files and directories that aren't accessible via the Finder (without special utility software). In most cases, you're better off leaving these files and directories alone, but if you need to see or work with invisible files and directories, the Terminal may be the best way to go.

Navigating the Mac OS X File System
Mac OS X, like most other operating systems, uses a file system to organize files and folders. The basic principle behind this system is that of hierarchy: at the top of the hierarchy is a single point (called the "root" of the file system, indicated by / in Unix systems), and below that point, a tree structure spreads out from directory to sub-directory.

In the Finder, you can easily see tree structure by looking at a window in column view. Open a new Finder window, choose View > As Columns, click on your startup disk, then Users, and then your user name. You should see at least eight folders in the fourth column. You're looking at the contents of your Home folder. Each of its sub-folders can contain other files and folders, and so on.

The rest of this article will show you how to move around in your Mac's file system using the Terminal. You will learn how to display the contents of a directory, how to change directories, and how to determine where you are.

Bear in mind that whenever you open the Terminal you are at a specific location in the file system. Unless you've modified how the Terminal works on your Mac (at which point you probably don't need these articles), you will always begin in your Home directory, the one with your user name (such as mine, called kirk). No matter what you do in the Terminal, you are always someplace.

Finding Where You Are with pwd
When traveling, you sometimes need to look at a map to find where you are. The same goes for the Terminal. The pwd command (print working directory) does just that by telling the Terminal to display the full path to the current working directory.

[Walden:~] kirk% pwd
/Users/kirk

I left the complete prompt visible in the above example to show you the difference between the directory information visible in the prompt (the ~) and what pwd displays. The only difference is that my user's Home directory is replaced by the ~ shortcut. But look at the next example. When I'm outside my Home directory, there's no difference between what is shown in the prompt and what pwd returns.

[Walden:/Library/Preferences] kirk% pwd
/Library/Preferences

Listing Directory Contents with ls
The ls command (list directory contents) is one of the most useful and commonly used commands for navigating the file system. You're used to seeing the contents of folders when opening new windows in the Finder; when you move to a new directory in the Terminal, you see nothing. The Terminal only displays the contents of a directory after you tell it to with the ls command.

When you are in your Home directory, and run the ls command, you should see something like this:

% ls
Desktop Library Music Public
Documents Movies Pictures Sites

The ls command returns a simple list of the current working directory's contents, but nothing in this list tells you anything about what these items are. Luckily, the ls command offers a plethora of options on how to display the contents of a directory, and what type of information is shown.

Viewing the Contents of a Different Directory
The ls command displays the contents of the current working directory (the one the Terminal is in) if you do not add the name of a directory to the command as an argument. You can list the contents of any directory on your computer, as long as you know its path. To do this, you must specify the full path of the directory. For example, if you want to list the contents of the /Library/Fonts directory, enter the following:

% ls /Library/Fonts
Arial Cochin.dfont HelveticaNeue.dfont
Arial Black Comic Sans MS Hoefler Text
Arial Narrow Courier New Optima.dfont
[etc.]

You must use the complete path of the directory /Library/Fonts/, because you are specifying an absolute file path. However, you can also use ls to display the contents of directories using relative file paths. When in my Home directory, I can display the contents of the Pictures directory by simply entering the following:

[Walden:~] kirk% ls Pictures/
iPhoto Library white background.jpg

As you can see from the prompt, I am still in my Home directory (~). If you don't specify an entire file path beginning with /, ls assumes you want to start from the current working directory.

Viewing the Entire Contents of a Directory
The basic ls command displays the contents of a directory in a simple manner. But what this command doesn't tell you is that there are other items in the directory. In fact, every Mac OS X directory contains invisible items, either files or folders. To view the entire contents of a directory, use the ls command with the -a option. (Note that options go before the directory path, if you're listing the contents of a specific directory as discussed just previously.)

% ls -a
. .Trash Desktop
.. .addressbook Documents
.CFUserTextEncoding .addressbook.lu Library
.DS_Store .lpoptions Movies
[etc.]

Your Home directory may contain different files, but many of them are the same. As you can see, there are a series of files beginning with . (dot). This dot indicates that a file is invisible, and the ls -a command displays all files, including invisibles. While you won't need to access most of these files (and messing with some of them could be harmful to your system), you can see them and know they are there. (Later in this article, when examining the cd command, we'll see what . and .. do.)

Viewing Long Information
Another option to the ls command, -l (that's a lowercase L), returns much more complete information on the contents of a directory, going much further than what you can find out from the Finder's Get Info command. If I run ls -l in my Home directory, the Terminal returns the following information:

% ls -l
total 0
drwxr-xr-x 3 kirk staff 102 Nov 9 11:22 Applications
drwxr-xr-x 8 kirk staff 272 Nov 11 14:46 Desktop
drwxr-xr-x 24 kirk staff 816 Nov 11 13:07 Documents
drwxr-xr-x 44 kirk staff 1496 Nov 10 22:49 Library
[etc.]

When you use ls with the -l option, the following information is displayed:


•The first line shows the number of 512-byte blocks used by files in the directory. In this example, there are no files - only directories - so it reads total 0.

•The first part of each line shows the file or directory's permissions.

• The next part is a number, showing the number of file system links the file or directory uses.

• Then comes the user name. In the above example, I am in my Home directory, so all the files belong to me.

• Next is the group the user belongs to. In this case, I belong to staff.

•The next number is the size of files in bytes, or the number of directory entries. This number is useful for files; the directory number is less useful.

•The date and time shown correspond to the last time the file or directory was modified. If the file has not been modified in the last year, the date and year are shown.

•Finally, the name of the file or directory is shown.

If you use ls -l in other locations, you may see additional information:


•Items belonging to other users, such as root.

• Additional groups, such as wheel, unknown, and admin, in addition to staff.

• Some items contain -> in their names. These are symbolic links, similar to Mac OS aliases. For example, var -> private/var is a symbolic link pointing from var to private/var.

While the ls -l command shows the size of files, there are some cases where this figure is incorrect. Adding the -s option adds a column, at the left of the list, showing the number of 512-byte blocks each file takes up on disk. Look at the following example:

% ls -ls
328 -rw-r--r-- 1 kirk staff 30819 Nov 14 18:06 Perceval.jpg
64 -rw-r--r-- 1 kirk staff 30819 Nov 14 18:07 PercevalCopy.jpg

These two files seem to have the same size (30819 bytes) but the first file takes up much more space on disk. This is because the first file, a picture, has an additional resource that the Terminal does not see. This thumbnail takes up much more space than the actual file, and the Finder clearly shows the difference in size. But the Terminal does not unless you use the -s option.

Changing Directories with cd
When navigating your Mac's file system in the Finder, you have two choices: you can either have the Finder open a new window when you open a folder, or it can open the new folder in the same window. When working in this second way, you always have just one window open, and you can go backward and forward in your file system hierarchy, but always within the same window.

Moving around in the Terminal works in this second way: no matter where you move to, you are always "in" one directory. As we saw above, the Terminal prompt tells you which directory you are in, and the pwd command tells you where you are in the file system hierarchy. So, remember that, when navigating the file system in the Terminal, you are always in one location.

The cd command (change directory) moves you from one directory to another. In Unix lingo, it changes the working directory; this is the directory in which you are located, and the one in which you can act on enclosed files or directories without specifying a file path. Let's start by looking at the following:

[Walden:~] kirk% ls
Desktop Library Music Public
Documents Movies Pictures Sites

The above shows the contents of my Home directory after executing the ls command. To move to the Library directory, type the following and press Return:

% cd Library
[Walden:~/Library] kirk%

The prompt changes to reflect the current working directory. (If you need to move into a folder whose name contains more than one word, enclose the folder name in quotes.) Then, to see what it contains, type ls and press Return.

% ls
Addresses FontFavorites.plist Preferences
Application Support Fonts Printers
Assistants Fonts (Disabled) Recent Servers
Audio Frameworks Screen Savers
[etc.]

You can move into one of these directories with cd:

% cd Addresses
[Walden:~/Library/Addresses] kirk%

And, look at its contents, using ls:

% ls
Address Book.addressbook Addresses.addressBook

At this time, you may have forgotten where you are in your file system. Use the pwd command to learn your location:

% pwd
/Users/kirk/Library/Addresses

You can now use the cd command to move back up in the hierarchy by running cd with the complete file path of the folder you want to move to. Say you want to go back to the Users/ directory; use the following:

% cd /Users
[Walden:/Users] kirk%

The prompt shows that you are in the Users directory. If you want to go back to the Library directory, where you were before, you could type the following:

% cd /Users/kirk/Library/
[Walden:~/Library] kirk%

If you attempt to move into a directory that does not exist, or if you misspell the name of a directory, you see this message:

% cd Proust
Proust: No such file or directory.

Using the Finder to Save Time in the Terminal
While you may think that the Finder and the Terminal are mutually exclusive, the two can work together to save you time. Sometimes, you may need to type a lot to get into a deeply nested directory, but it's a cinch to navigate there in the Finder. If you want to move into a directory using cd, type cd [space] in the Terminal. Then switch to the Finder, look for the folder you want to move to, and drag that folder into the Terminal window. The Terminal adds the path of the item you drag to the command you just typed.

[Walden:~] kirk% cd /Users/kirk/Library/Preferences

Press Return, and that directory becomes your current working directory.

You can do the same thing to act on a file. Just type the beginning of the command you want to use (don't forget to type a space before dragging the file), then locate the file in the Finder, and drag it to the Terminal window.

Going Home in a Jiffy
It may seem as though using the cd command requires a lot of typing, and in its basic usage, that can be true. However, cd also offers many shortcuts to let you navigate quickly and easily through the file system. The most useful shortcut is to type just cd, then press Return, which we do while our current working directory is the Addresses directory, as you can see in the prompt below.

[Walden:~/Library/Addresses] kirk% cd
[Walden:~] kirk%

As you can see from the second prompt, cd by itself takes you to your Home directory. (Remember, the tilde character (~) is a shortcut for the current user's Home directory.) The reason for this shortcut is that Unix assumes most users will only be working in their Home directory or one of its sub-directories. For this reason, the tilde (~) shortcut for your Home directory also lets you move easily to sub-directories within your Home directory. If you want to move to your Documents directory, you can type the following no matter where you are:

% cd ~/Documents
[Walden:~/Documents] kirk%

Using the ~ shortcut helps save you from typing the full file path of the Documents directory.

Upstairs Downstairs
Every directory in your file system contains at least two entries. When you create a new, empty directory, these two "files" are automatically added to them. They are . (dot) and .. (dot dot). Look at the following:

% mkdir New_Directory
% cd New_Directory
% ls -a
. ..

In the first line above, I created a new directory, and, in the second line, I moved into that directory. I then ran the ls -a command, which displays the contents of that directory; the -a option shows invisible files. You can see that the only files in this new directory are . (dot) and .. (dot dot).

These two files are useful. The first one, . (dot), represents the current working directory, and can save you time in certain commands involving files within that directory. The second one, .. (dot dot), is a shortcut to the parent directory, or the next directory up in the file system. No matter where you are in the file system, you can always type the following:

[Walden:~/Documents/New_Directory] kirk% cd ..
[Walden:~/Documents] kirk%

As you can see from the prompts in this example, typing cd .. takes you up to the parent directory of New_Directory, or Documents. Any time you move into a sub-directory, using the cd command, you can use cd .. to back up. But you can also move up the file system from the current directory until you reach the top. Look at the following:

[Walden:~/Documents] kirk% cd ..
[Walden:~] kirk% cd ..
[Walden:/Users] kirk% cd ..
[Walden:/] kirk%

As you can see in the prompts, I was in my Documents folder, then moved up three times to reach the root level of the file system, or /.

You can now combine the cd .. command with cd - to move up and down in the file system, but, remember, the cd - command only moves back one step. There is no simple equivalent (in the cd command) to move down the file system to where you started.

[Walden:/Users] kirk% cd ..
[Walden:/] kirk% cd -
[Walden:/Users] kirk%

In the first line, I moved up from /Users to /; in the second line, I moved back to the previous working directory, /Users.

Opening a Directory in the Finder
Sure, the Terminal lets you move around quickly and easily, yet all but the most die-hard Unix fans will eventually yearn to see icons again. Wherever you are in the Terminal, no matter what directory you are in, you can run the following command at any time to open the current working directory in a new window in the Finder:

% open .

You will recall that . (dot) represents the current working directory. The open command lets you open many kinds of items just as if you double-click them. The open command even lets you open directories that are normally hidden from view by the Finder, thus giving you the best of both worlds.

Home Again
This article showed you how to move around your Mac's file system, and how to see what its folders (or directories) contain. You learned about how the Mac OS X file system works, and saw some of the differences between what you see in the Finder and what Terminal shows you. You discovered some of the basic commands for navigating your computer, which are the command-line equivalents of double-clicking folders and reading their contents:


• pwd: tells you where you are.
• cd: takes you into another directory.
• ls: shows you what your directories contain
• open: opens a directory in a new window in the Finder.
• You also learned how to use the ~ (tilde) character as a shortcut for your Home directory.

In the next installment, you'll learn how to move and copy files, how to create directories, and how to delete files and directories, rounding out the basics of command-line navigation.

Moving, Copying, and Deleting Files and Directories

In the previous two installments in this series, we looked at the basics of using the Terminal to access the Unix command line at the heart of Mac OS X, and then at how to use the Terminal to move around your Mac's file system. You might want to skim those articles for a quick refresher on some of the basics.

<http://db.tidbits.com/ getbits.acgi? tbser= 1238>

One of the strongest features of the Mac OS X Finder is its capability to make file management actions so easy that they seem effortless. When you drag a file's icon from one window to another, for example, the Finder puts a graphical face on a basic action, that of issuing a command to move a file from one location to another.

It's certainly quicker and easier to move icons in Finder windows than to type commands, but the command line offers advantages over using the Finder for moving, copying, or deleting files and folders (or directories). Here are just a few:


• You can copy or move files from one directory to a distant directory, without having to navigate through intermediate windows.

• You can easily copy or move multiple files using wildcards (a wildcard is a single character that represents one or more other characters). You can even select which files to copy according to certain attributes, such as parts of file names or extensions.

• You can copy or move files that are hidden by the Finder.

• You can move and rename a file or directory with just one command.

• You can delete files or directories quickly, and use wildcards to match certain file name strings (such as .jpg, .rtf, and so on). These deletions are irreversible, so be careful!

• You can delete files that the Finder refuses to delete; occasionally, a recalcitrant file you have placed in the Trash just won't go away. Using the command line, you can eliminate it for good.

As you become more familiar with working with the command line, you will discover more advantages to using it for file manipulation.

A Caveat on Moving and Copying Files
The Mac OS has historically used a unique way of saving files: many files are in two parts, called the data fork and the resource fork. Back in the days of Mac OS 9 and earlier, the data fork contained data (the contents of a file, or code for applications) and the resource fork contained settings, icons, and other information. Most files used this multi-fork system, and, if you ever copied Mac files to a PC-formatted floppy disk and then looked at it on a Windows computer, you could have seen additional folders copied together with your files. These folders held resources forks; since Windows doesn't understand multi-forked files, putting the resource forks in a separate folder was one way of keeping Windows from deleting them altogether. Unfortunately, and almost shockingly, the standard Unix commands available in Mac OS X don't understand resource forks either.

When copying or moving files containing a resource fork, this can be a serious problem: some files still contain information in a resource fork, especially applications and those files created by Classic applications, as well as some Mac OS X-native applications. The cp and mv commands strip any resource forks they come across, potentially rendering the files useless. Apple addressed this problem by creating some additional commands, called CpMac and MvMac (the capitalization is important here), to resolve these issues, but for some reason, these commands are installed only with the Developer Tools, so most people probably don't have them installed. These command line tools enable you to copy and move files while retaining their resource forks, thus ensuring that everything you copy or move with them remains usable.

Another command, called ditto, has a -rsrcfork option, which, like CpMac and MvMac, allows you to retain resource forks when copying files.

Copying Files with cp
The cp (copy) command does exactly what its name suggests: it copies files from one location to another. (This is the equivalent of pressing Option while dragging files in the Finder from one window to another on the same volume.) In its simplest use, cp copies a file (specified by its file name, with either a relative or absolute path) to a directory (also specified by its name, with either a relative or absolute path). The basic form is as follows:

% cp source destination

With this in mind, let's look at a few examples of copying files.

% cp ~/Documents/MyFile.rtf ~/Public

In the above example, I copied the file "MyFile.rtf" from the Documents directory in my Home directory to the Public directory, a location where any user can access files. As you can see, the first part, cp, is the command, the second, ~/Documents/MyFile.rtf, is the source, and the third part, ~/Public, is the destination. Both the source and destination in this example use absolute file paths; I could be anywhere in the file system when running this command.

However, if I were already in the Documents directory, I wouldn't need to use an absolute file path for the source. Since it's perfectly legal to mix absolute and relative file paths in a command, I could merely type the following:

% cp MyFile.rtf ~/Public

When copying files in this simple form, the source is a file name and the destination is a directory. (Though the destination can also be a file name; see below for more ways to use cp.) But the source can also be multiple file names. When executing this command, the shell (which is the Unix program that accepts your typed commands, interprets them, and displays the results) checks the contents of the directory you refer to, making sure that the file or files exist. If there are several files listed in what you've typed, and they all exist, then the shell goes ahead and copies them all to the destination. You can run a command like this to copy the three files after the cp command to the Public directory:

% cp MyFile1.rtf MyFile2.rtf MyFile3.rtf ~/Public

Using Wildcards to Copy Files
For an even shorter version of the previous command, you can use a wildcard and save some typing:

% cp MyFile* ~/Public

The * wildcard tells the shell to look for all files whose names begin with MyFile, and copy them to ~/Public. Of course, if you have 10 files like that, all 10 will be copied. If you want only the first three copied, you must enter each name individually, or you could use the following command:

% cp MyFile[1-3].rtf ~/Public

If you want to copy all .rtf files from the source directory, you can use the following:

% cp *.rtf ~/Public

This command copies all files ending with .rtf to the Public folder. You can use the asterisk wildcard at any location in a file name.

Warning: Copying Files Replaces Existing Files
By default, the cp command silently replaces any like-named files in the destination, unlike the Finder, which displays an alert asking if you really want to replace them. The same goes for the mv command (see below). This is one of the dangers of using the command line - new actions call for new habits, and the safest way to work with these two commands is to use the -i (interactive) option, which tells the shell to ask you if any files with the same name are present. When using this option, type y for yes (to replace files) and n for no. Here's an example:

% cp -i MyFile1.rtf New_Directory/
overwrite New_Directory/MyFile1.rtf? y
%

If I had typed n at the overwrite question, the command would have stopped without doing anything.

Copying a File and Changing Its Name
In the above examples, the sources used were files and destinations directories. But the destination can also be a file name. This is useful if you want to copy a file and change its name at the same time. For example, to copy MyFile.rtf to your Public folder, renaming it MyFile1.rtf, run the following command:

% cp MyFile.rtf ~/Public/MyFile1.rtf

You can do the same thing to make a copy of a file, with a different name, in the same folder. Just run the command like this:

% cp MyFile.rtf MyFile1.rtf

Copying Directories with cp
You can use cp to copy directories as well as files, but it works a bit differently. For cp to work with directories, it needs the -R (recursive) option. The -R option tells cp to copy not only the directory specified, but also all sub-directories it contains as well as any other contents. To copy a directory, you need to run a command using this basic form:

% cp -R source destination

All the other options and ways of copying, shown above for files, work the same with directories. Note, however, that while you can change the name of a directory during a copy, you cannot change the name of its sub-directories or other contents.

Moving Files and Directories with mv
The mv (move) command moves files or directories from one location to another. It works just like when you drag files from one Finder window to another on the same volume. Note that if you run the mv command across volumes, the files or directories are removed from their original location, whereas the Finder normally copies them across volumes unless you hold down Command while dragging them. The mv command thus acts like a cut and paste operation, cutting the file or directory from its original location, and pasting it in its new location. The mv command works almost exactly like the cp command, the main exception being that you never have to use the -R option to move directories. To use mv, try the examples described above, substituting mv for cp.

% mv MyFile.rtf ~/Public/MyFile.rtf

In the above example, the file called MyFile.rtf is moved to my Public folder. The operating system first writes the file, then, after checking to make sure the copied file was written correctly, it deletes the original.

By default, the mv command (just like cp) replaces any like-named files in the destination. This behavior is unlike the Finder, which displays an alert, asking if you really want to replace them. You can run the mv command with the -i (interactive) option, as with many commands, to protect against this possibility.

Renaming Files and Directories with mv
Since you can change the name of the destination when moving files or directories with mv, you can also use it to rename items, such as in this example:

% mv MyFile.rtf NewlyNamed.rtf

Unfortunately, renaming a bunch of files at once with wildcards (such as prefixing each of many files with a specific string) isn't trivial; the best way to do that is with the Add and Trim AppleScript scripts that Apple includes with Mac OS X; you can find them in /Library/Scripts/Finder Scripts.

Creating Directories with mkdir
We have seen above how to move and copy files from one directory to another, but you may also need to create directories to put these files in. The mkdir (make directory) command is easy to use. Here's an example:

% mkdir Test

This command creates a new directory, called Test, in the current directory. Since the command does not begin with a /, the shell knows that you are specifying a relative path. If you want to create the same directory in, say, your Documents directory, you could run the above command after using cd (change directory) to move to that directory, or, from anywhere, run the following:

% mkdir ~/Documents/Test

The mkdir command can also make several directories at a time. If you want to create three directories, called Test1, Test2, and Test3, in the current working directory, you can run the following:

% mkdir Test1 Test2 Test3

If you want to create directories in hierarchy, mkdir can help as well. The only condition is that you set up your command in hierarchical order, creating the parent directory before the sub-directory, and before the sub-sub-directory, and so on. To create a series of directories and sub-directories like this:

Test1/Test2/Test3

you need to run the command as follows:

% mkdir -p Test1/Test2/Test3

The -p (path) option tells the command to create each intermediate directory as required. The command first creates the Test1 directory, then the Test2 sub-directory, and finally, further down in the hierarchy, Test3.

Removing Directories with rmdir
The rmdir (remove directory) command is self-explanatory: it lets you remove directories, deleting them forever. Like the rm command that works on files, this command is extremely powerful: once you remove a directory, there is no getting it back.

However, rmdir works only with empty directories, whereas rm works with both directories and files, thus enabling you to delete a directory and the files in it. You may find it easier to use rm for both files and directories - it's easier to use one command instead of two.

To delete an empty directory, run the following:

% rmdir Directory1

You can remove several empty directories in one command. Just separate their names with single spaces, specifying either just their names (for relative paths, within the current working directory), or their paths (for absolute paths). Here's an example that removes three directories at once - Directory1, OldDocuments, and Video - and uses a different way of specifying each one:

% rmdir Directory1 ~/Documents/OldDocuments ../Video

You can also use rmdir to remove a hierarchy of directories, as long as all the directories are empty. Use the -p (path) option as follows:

% rmdir -p Directory1/Directory2/Directory3

One disadvantage to using the rmdir command is that, unlike the rm command, it has no -i (interactive) option, which asks you to confirm the deletion, and no -v (verbose) option; these deficiencies limit its value.

Removing Files with rm
The rm (remove) command is one of the most powerful and dangerous commands you can use in the Terminal. Be forewarned: when you remove a file with rm, it is deleted forever. Although some file recovery programs may be able to find files deleted in this manner, it is safest to assume that files eliminated with rm are gone for good. Be even more careful with rm if you use it with the * wildcard, since it could wipe out all the files in a directory with no warning.

Although many Unix commands are safe to run, even if you have little experience, rm is like a loaded gun. For this reason, you should use it with the utmost care. However, there is a simple way to apply a safeguard to rm (and others); see below for a safety measure that takes the worry away.

Running the rm command is relatively simple. Look at the contents of this directory with ls:

% ls
File1 File2 File3

To remove one of these files, run the following:

% rm File1

Check to make sure it worked with ls again:

% ls
File2 File3

You can see that the file you removed is indeed gone; it no longer shows up in the list.

Safer Ways Remove Files
The first way of removing files, as shown above, is really for those people who are confident with the command line. It's working without a net, though, and there is a simple safeguard you can use to protect yourself. The rm command has an option, -i (for interactive), which tells the shell to ask you to confirm that you really want to delete each file. To use this option, run the command as follows:

% rm -i File2

The shell asks you to confirm.

remove File2?

Type y for yes or n for no.

remove File2? y

If you type y, the file will be deleted. If you type n, the file will not be touched. In both cases, the Terminal displays a new prompt; it gives no other information, and you need to use ls again to see what's in the directory.

Want an even safer way to remove files? Mimic the way the Finder does it and move them to the Trash. Then they won't be deleted until you empty the Trash manually. Try this mv command:

% mv MyFilertf ~/.Trash

Getting More Feedback with rm
The rm command has another option, -v (verbose), which shows the names of files as it removes them. If you use this option, the shell shows the following:

% rm -v File3
File3
%

I have added the prompt after the file removal to illustrate how this displays. All this option does is show the name of the file, but it can serve to confirm exactly which file has been removed. Of course, if you made a typo and removed the wrong file, it's too late!

Removing Directories with rm
Although you can use rmdir for removing empty directories, the rm command also lets you do this through the -d option. To remove a directory, use the following command, along with the -i and -v options for additional security:

% rm -div Directory1

The rm command can also remove directories recursively, using the -r (recursive) option, deleting a directory and all its subdirectories, as well as any files they contain. This is like dragging a folder, containing sub-folders and files, to the Trash in the Finder, except you can't drag it back out of the Trash if you want to keep it. If rm is a loaded gun, rm -r is a loaded bazooka. I cannot stress strongly enough how dangerous this command is, since you could blow away large numbers of files with a single mistake!

Let's look at how this works, and how you can use the -i option for minimal protection. First, create a few nested directories:

% mkdir -p Directory1/Directory2/Directory3

Then, to remove all three of these directories, run the following:

% rm -ir Directory1
remove Directory1? y
remove Directory1/Directory2? y
remove Directory1/Directory2/Directory3? y

Obviously, if you don't use the -i option, the command just removes all the directories without any feedback. But what if you decide you don't want to remove one of the directories? You can type n at any point to keep it and each directory above it. Watch what happens then:

% rm -ir Directory1
remove Directory1? y
remove Directory1/Directory2? y
remove Directory1/Directory2/Directory3? n
rm: Directory1/Directory2: Directory not empty
rm: Directory1: Directory not empty

If, at any point in the hierarchy, you don't want to delete a file or directory, the system cannot let you keep an item without its parent directory. In the above example, the decision to not remove Directory3 means that Directory2 (its parent directory) could not be deleted; Directory1 (the parent of Directory2) also could not be deleted, so none of these three directories will be removed.

Summing Up
This installment has shown you the essential commands for copying, moving, and deleting files and directories, as well as creating directories. These commands - cp, mv, rm, mkdir and rmdir - offer the same basic functions as normal Finder actions, but, as some of the examples show, offer more power and flexibility in certain situations. While the Finder remains easier to use for most operations, these commands give you a powerful alternative, with some capabilities the Finder cannot offer.

[Kirk McElhearn is a freelance writer and translator living in a village in the French Alps. This article is an excerpt from his forthcoming book, Unix for Mac OS X: Learning the Command Line, to be published by Addison-Wesley in 2003.]

<http://www.mcelhearn.com/ unix.html>

Reprinted with permission from TidBITS#693/18-Aug-03. TidBITS has offered more than ten years of thoughtful commentary on Macintosh and Internet topics. For free email subscriptions and access to the entire TidBITS archive, visit www.tidbits.com.


Home | About | Meetings | Links | Contact | Join | Forums

Wellington Macintosh Society Inc. 2002