Chapter  23

Introducing Darwin and the Mac OS X Command Line

Running behind the slick Mac OS X Aqua GUI is Darwin, the POSIX-compliant, UNIX-based environment that forms the foundation of Mac OS X. While the majority of Mac OS X users never find it necessary to use the command line, for those that are willing to learn there is whole new world of powerful computing awaiting.

In this chapter you will learn

  • The basics of Darwin and the command line
  • Common and useful command-line commands
  • The power and pitfalls of working as root
  • Editing files with Vim, Emacs, and Nano
  • What file attributes are and how to change them
  • Customizing your command-line environment

Darwin Basics

Included in Darwin is a collection of many powerful tools that are not only used by many functions of Mac OS X, but are also available for you to use. The most direct way to interact with Darwin and take full advantage of all these wonderfully powerful UNIX tools is through the use of the Terminal application (/Applications/Utilities/Terminal). When Terminal is launched, it opens up a terminal window running a shell program, as shown in Figure 23-1.

Image

Figure 23-1. The Terminal application running in Mac OS X

Before we jump to far ahead of ourselves, though, there are a few things worth learning up front that will be helpful on your journey into the command line. The first thing you need to know when working with Darwin is some of the common language and terms used when talking about a command-line environment, in order to avoid confusion. Next, you need to know how files are organized; and finally, you need to know how to move around the file system.

NOTE: When we talk about files here, we are not just talking about the last text file you created; Darwin treats everything as a file. For example, a directory (aka folder) is a file that contains other files. Each file has a number of properties that determine how the shell treats that specific file; if it's an application, the shell will launch it; if it's a directory, the shell will know that it can access other files contained in it. We'll cover file properties a bit later.

Darwin Semantics

To avoid confusion as the chapter proceeds, we should quickly go over some of the important terms used in Darwin and how they compare with terms used in the Finder. Table 23-1 defines a handful of terms used commonly in Darwin (and other UNIX systems), gives the Finder equivalent or alternate term, and adds any relevant notes. While there are many other terms you'll come across, these basics will be used repeatedly, so they are good to know.

Image

Image

The File System

The Darwin file system shares the same folder structure found while navigating through the Finder. However, while navigating through Darwin, you will notice a few differences. First, there are quite a few more visible items in the Darwin view. Second, you will find that your additional volumes (added hard drives, CD/DVD drives, flash drives, etc.) are found a little differently.

The Darwin file system starts from root, which is symbolized by /. This is the highest level of the file system and is essentially the same as viewing your primary hard drive in the Finder. A quick look in our root directory reveals the following items (the trailing / and @ symbols that follow have special meaning and are only visible when you use them with the F flag: / indicates that the item is a directory [or folder], and @ indicates that the item is a link [or alias]):

Applications/  System/    cores/          mach_kernel     tmp@
Developer/     Users/     dev/            net/            usr/
Library/       Volumes/   etc@            private/        var@
Network/       bin/       home/           sbin/

As you can see, all the basic Finder folders—Applications, Library, System, Users, and Developer (provided you've installed the Xcode tools)—are there, along with a slew of other items. Some of these are merely system files that are of little interest to most people. Table 23-2 shows some common directory paths and describes what sorts of files are located in them.

Image

Introducing the Shell

The Terminal application (go ahead, fire it up) is essentially an empty window that can display and accept text input. In order for you to actually do anything, Terminal must run a shell program. Just as the Finder allows you to move around and interact with items in Mac OS X's GUI, the shell allows you to move around and interact with items on the command line. Bourne, Tcsh, and Zsh (the C shell is also listed as a shell—however, it is actually a link to Tcsh). Of the five, the shell Mac OS X uses by default is Bash.

NOTE: Originally, Mac OS X used Tcsh by default, but switched to Bash with the release of OS X 10.3 Panther. If you are new to working with UNIX shells, I'd recommend sticking with Bash, at least while you are learning. The lessons in this book, unless specifically noted, are all given using the Bash shell.

The first time you launch Terminal, you'll be greeted by some text similar to this:

Last login: Wed May 25 15:09:30 on console
Simba:~ scott$

The first line tells you when you last logged into Darwin (even if you've never logged into Darwin before intentionally, you'll still get a message saying you did); the second line is the default prompt for Bash. The default prompt (which, like most everything else in Darwin, can be changed) gives you some important information. First, it gives you the name of your computer, which is either assigned by your network or taken from the Computer Name field in the system's Sharing preference pane. Next, following the :, the prompt gives you the name of your current directory in the file system (the ~ is a shortcut representing your home directory). Then the prompt gives you the username you are logged in as, followed by the $ prompt (which will change to a # if the user is logged in as the root user, otherwise known as the super user). Finally, you get the cursor patiently a waiting your command.

As you will soon see, shells possess some hidden powers that can make your interactions with Darwin more pleasant and add a new level of power and flexibility to the command line. Before you look at the shell in more depth, though, you should first learn a bit about the Darwin file system, as well as a few basic Darwin commands.

Moving Around Darwin

One of the first things you need to learn about the shell is how to move around and view the file system. To do this, there are three basic commands to start with: ls, cd, and pwd.

ls

ls is the “list” command, and by default, lists all the visible files in a directory. If you're familiar with the Windows command line, it would be the replacement for dir. By default, the ls command looks something like this:

Simba:~ scott$ ls
Desktop         Downloads        Movies         Pictures
Documents       Library          Music          Public

The first thing you may notice is that by default all directories (folders), files, and executables (applications) look the same when using the ls command (of course, in this example, they all are directories). That's because, as we mentioned previously, Darwin treats everything as a file. To differentiate between the different types of files, there are two primary options:

  • ls –F: Appends special files with a symbol to determine their type. It adds a / to directories, an * to executables, an @ to symbolic links (aliases), and a few other symbols for other special file types.
  • ls –G: Colorizes the output using different colors for different file types as well as other file options. For example, by default most directories will appear blue; however, world-writable directories will appear black with a yellow background. Likewise, most executables will appear red, and most symbolic links will appear purple—however, if certain attributes are set, this will not always be the case.

NOTE: One thing immediately noticeable to users moving to Darwin from Linux is that certain command-line commands are slightly different. For example, to colorize your output in Linux, one would traditionally use ls --color, and in some cases the output colors are different. This difference exists because UNIX comes in many different flavors, and occasionally there is slight deviation in commands from one to the other. For example, some UNIX tools are derived from the traditional BSD (Berkeley Software Distribution) camp, and they differ in some subtle ways from tools from the GNU camp. Linux almost always chooses its tools from the GNU camp, while Darwin tends to favor the BSD camp. While in general the tools will work the same, there are a few cases where there are minor differences—colorizing ls is one of those differences.

Like most command-line commands, the options can be combined. For example, you can use -F and -G together:

Simba:~ scott$ ls -FG
Desktop/   Downloads/ Movies/    Pictures/
Documents/ Library/   Music/     Public/

Other important ls options include the following:

  • ls –l: Displays a long list that provides additional information about each file. We'll cover what everything here means later in the “File Permissions and Attributes” section of this chapter, but for now the results appear to be something like this:
    Simba:~ scott$ ls -l
    total 0
    drwx------+  5 scott  staff   170 May 15 09:28 Desktop
    drwx------+  8 scott  staff   272 May  6 15:13 Documents
    drwx------+ 14 scott  staff   476 May 25 16:18 Downloads
    drwx------@ 42 scott  staff  1428 May 15 18:29 Library
    drwx------+  3 scott  staff   102 Apr 28 18:42 Movies
    drwx------+  4 scott  staff   136 May  7 13:54 Music
    drwx------+  5 scott  staff   170 Apr 30 13:53 Pictures
    drwxr-xr-x+  5 scott  staff   170 Apr 28 18:42 Public
  • ls -a and ls –A: Prints out a file listing that includes hidden dot files. There are two main types of files hidden on your computer: some that are hidden by default from the Finder but show up normally in Darwin, and others (the dot files) that are generally hidden in Darwin. These dot files (called that because they always begin with a .) are often preference or configuration files. They are usually hidden to reduce clutter, not for some nefarious purpose (although you may find that some Aqua applications utilize these hidden files to hide something they really don't want you to find). The main difference between ls -a and ls -A is that using ls -a will show two special files found in almost every directory—the . and the ..—which represent the current directory and the directory immediately above, respectively (these act the same as the . and ..files shown when issuing a dir command at the Microsoft Windows command prompt). A common ls -a on a home directory will produce quite a few more files than just a vanilla ls (three times as many or more is not uncommon):
    Simba:~ scott$ ls -a
    .                                .cups                Movies
    ..                               Desktop              Music
    .CFUserTextEncoding              Documents            Pictures
    .DS_Store                        Downloads            Public
    .Trash                           Library

While there are significantly more options available for the ls command, those are the most common and should get you started on the right path. You may learn a few other options as you go along, and later you'll learn about the man command, which will allow you to learn more about the ls command (and most others) than you care to know.

Listing a Directory Other Than Your Current Directory

Besides ls's many options, ls will also accept a directory or file name as an argument. This allows you to view the contents of any directory without actually moving into that directory, or explore a single file's attributes (using the -l option). For example, if you're in your home directory but want to view the files in your Documents folder, your can do this by adding Documents as an argument—for example:

Simba:~ scott$ ls -F
Desktop/        Downloads/   Movies/        Pictures/
Documents/      Library/     Music/         Public/
Simba:~ scott$ ls -F Documents
About Stacks.lpdf/      Microsoft User Data/
Learn Lion              Snagit/

Furthermore, if you want to find out more about a specific file, you can enter a command like this:

Simba:~ scott$ ls -l Documents/Hello
-rw-r--r--  1 scott  staff  45 May 25 18:11 Documents/Hello

Now that you know how to list other directories, the next thing you may want to learn is how to move into them (virtually anyway).

cd

The cd command allows you to move from one directory to another (or as the command implies, it allows you to change directories). The cd command doesn't have any options, and it only accepts a path name as its single argument.

NOTE: cd is kind of special in that, unlike ls, it is not an executable file—rather, it is a special type of command referred to as a built-in command. This command, along with a few others you will learn about, is a function of the shell and not traditionally a separate executable file. Although most common built-ins like cd exist in all common shells, it is possible that a built-in command in one shell will behave slightly differently from one in another (cd isn't one of these—it behaves the same way in every shell we've used over the past 20 or so years).

To issue the cd command, simply type cd followed by your destination, like so:

Simba:~ scott$ cd /
Simba:/ scott$

If no argument is given, then cd will take you back to your home directory:

Simba:/ scott$ cd
Simba:~ scott$

Finally, if cd doesn't recognize the argument as a file or directory, it will tell you so:

Simba:~ scott$ cd /blah
-bash:  cd:  /blah:  No such file or directory
Simba:~ scott$

This is an error statement, and most well-written functions and executables will provide some sort of error message if the information you provide doesn't make sense to them.

CAUTION: Although well-written commands often give you an error message when you do something wrong, it's important to note that this only happens when the command has no idea how to parse the information you've given it. However, this will not prevent all erroneous commands from executing. If a command is recognized as valid, even if the information you enter isn't, the command will execute. While this is often harmless, it can have disastrous consequences (the rm command, as you will soon learn, deletes files immediately and permanently and can cause all sorts of badness if used poorly).

pwd

The final command in this section is the pwd command. The pwd command returns your current working directory, as this information is available by default in your prompt (after the :). You may not need to use this command too often—however, it is useful in illustrating the file structure of the system and can come in handy when you need to pass your current path into a script. Also, it's possible that you may find yourself stuck in a foreign shell on a foreign machine, where you may actually need this. The basic pwd command looks like this:

Simba:~ scott$ pwd
/Users/scott

In this case, pwd returns the absolute path of your home directory rather than the abbreviated ~ in the command prompt.

Being a rather simple command, pwd only offers two extra options:

  • pwd -L: Prints the logical path to your working directory
  • pwd -P: Prints out the physical path to your working directory, resolving any symboliclinks

    NOTE: Logical paths and physical paths have to do with resolving symbolic links and aliases. For example, if you entered cd /etc and then entered pwd –L, the output would be /etc because that is where you are (logically); however, since /etc is a symbolic link, entering pwd –P would provide you with the actual physical location /private/etc.

Wildcards

Before moving on to more Darwin commands, we should have a quick lesson on wildcards and pattern matching. Wildcards are special symbols that, when used with other commands, can help limit or expand the results. Table 23-3 shows the three major wildcards and what they represent or match.

Image

To put this to use using what you learned previously, if you cd to /usr/bin and list out the contents using ls, you are struck with a rather large list of files (in this case, mostly executable commands). Wildcards allow you to selectively list out the directory contents in more manageable chunks. For example, if you just wanted to list the files that begin with v, you could use ls v*, like so:

Simba:bin scott$ ls v*
vacuumdb        vi                vimdiff                vm_stat
vers_string     view              vimtutor               vmmap
vgrind          vim               vis

If, for whatever reason, you wanted to expand the search to include b and v, you could use ls [bv]*:

Simba:bin scott$ls [bv]*
banner         binhex         bzcmp         bzmore         vimtutor
base64         bison         bzdiff         vacuumdb       vis
basename       bitesize.d    bzegrep        vers_string    vm_stat
bashbug        bsdmake       bzfgrep        vgrind         vmmap
batch          bsdtar        bzgrep         vi
bc             bspatch       bzip2          view
bg             bunzip2       bzip2recover   vim
biff           bzcat         bzless         vimdiff

Note that like most things in Darwin, the characters used within the square brackets are case sensitive, so [bv] would not match any Bs or Vs.

Finally, if you wanted to list all files with two-letter names that begin with any letter in the alphabet from b to v, you could use ls[b-v]? and get the following:

Simba:bin scott$ ls [b-v]?
bc  cd  cu  ex  id  m4  nl  pl  rs  ul
bg  ci  dc  fc  ld  md  nm  pr  su  vi
cc  co  du  fg  lp  nc  od  ri  tr

Working with Files and Directories

While most people are perfectly happy and comfortable working with files and directories in the Finder, there are some times when it's either necessary or advantageous to work with files on the command line. Of course, like all things, before you are able to unleash the power of the command line, you need to learn a few basic commands for working with files and directories. These basic commands are shown and described in Table 23-4.

Image

CAUTION: Irresponsible use of rm can result in very bad things happening—for example, if you happen to be utilizing root privileges (which, in general, you probably shouldn't), and happen to type rm -R /* at the command line, your system will immediately begin to delete itself and everything contained within it until it deletes enough of itself that it can't continue . . . ever. (By the way, the -R option stands for recursive, a handy option found in many commands.) If you want to be extra careful you could use the -i option, which will ask for confirmation for each file to be deleted.

To illustrate how all of these work, we've created a test file named soliloquy4 in a directory named Shakespeare.

First, you can use the cat command to view the file:

Simba:Shakespeare scott$ cat soliloquy4
Tomorrow,  and tomorrow,  and tomorrow,
Creeps in this petty pace from day to day
To the last syllable of recorded time,
And all our yesterdays have lighted fools
The way to dusty death. Out,  out,  brief candle!
Life's but a walking shadow,  a poor player
That struts and frets his hour upon the stage
And then is heard no more:  it is a tale
Told by an idiot,  full of sound and fury,
Signifying nothing.

Now, if you weren't sure what this file was (or how long it was), you could use head to view just the first three lines:

Simba:Shakespeare scott$ head -n 3 soliloquy4
Tomorrow,  and tomorrow,  and tomorrow,
Creeps in this petty pace from day to day
To the last syllable of recorded time,

Likewise, you could use tail to view the last three lines:

Simba:Shakespeare scott$ tail -n 3 soliloquy4
And then is heard no more:  it is a tale
Told by an idiot,  full of sound and fury,
Signifying nothing.

NOTE: Like many OSs these days, OS X keeps rather long log files about many of the things happening on the system. While there are many dedicated viewers for many of these files, these files are often very, very long. For such files, tail can be a godsend. For example, if you run a busy web server for which you want to see the details of the last 50 hits, you could use tail -n 50 /var/log/apache2/access_log.

To make a copy of the file, you would use the cp command:

Simba:Shakespeare scott$ ls
soliloquy4
Simba:Shakespeare scott$ cp soliloquy4 macbethsolo
Simba:Shakespeare scott$ ls
macbethsolo    soliloquy4

You could then create a new subdirectory:

Simba:Shakespeare scott$ mkdir Macbeth
Simba:Shakespeare scott$ ls
Macbeth/         macbethsolo    soliloquy4

and then move one of the files into the new directory:

Simba:Shakespeare scott$ mv soliloquy4 Macbeth/soliloquy4
Simba:Shakespeare scott$ ls
Macbeth/           macbethsolo
Simba:Shakespeare scott$ ls Macbeth/
soliloquy4

You can also use the mv command to rename a file:

Simba:Shakespeare scott$ mv macbethsolo tomorrow
Simba:Shakespeare scott$ ls Macbeth/
tomorrow

Next, you could try to remove the Macbeth directory:

Simba:Shakespeare scott$ rmdir Macbeth/
rmdir: Macbeth/:  Directory not empty

Oops, first you need to remove any files in there:

Simba:Shakespeare scott$ rm Macbeth/*
Simba:Shakespeare scott$ rmdir Macbeth
Simba:Shakespeare scott$ ls
tomorrow

Finally, you can create a new empty file with touch:

Simba:Shakespeare scott$ touch nothing
Simba:Shakespeare scott$ ls
nothing     tomorrow
Simba:Shakespeare scott$ cat nothing

Simba:Shakespeare scott$

More Essential Commands

There are literally hundreds of commands available at the command line, and it would take far more space than we have in this book to cover them all; however, as you progress through the rest of the book, you will learn a number of new commands when they are applicable to the topic at hand. In the meantime, there are a number of essential, or at least very useful, commands that you may want to know about that don't fit nicely in a future discussion in this book. They are covered here.

man

The man command is the command that explains all others. If you want to learn more about the ls command, enter man ls, and your terminal will open into a special mode (called a pager) for reading man pages, which will look something like this:

LS(1)                     BSD General Commands Manual                    LS(1)

NAME
     ls -- list directory contents

SYNOPSIS
     ls [-ABCFGHLOPRSTUW@abcdefghiklmnopqrstuwx1] [file ...]

DESCRIPTION
     For each operand that names a file of a type other than directory, ls
     displays its name as well as any requested, associated information.  For
     each operand that names a file of type directory, ls displays the names
     of files contained within that directory, as well as any requested, asso-
     ciated information.


     If no operands are given, the contents of the current directory are dis-
     played.  If more than one operand is given, non-directory operands are
     displayed first; directory and non-directory operands are sorted sepa-
     rately and in lexicographical order.


     The following options are available:

:

Now this is just the first page of the man page—you can scroll through the rest using either the arrow keys (to move up and down one line at a time) or the spacebar (to move through one page at a time). When you are done, you can exit the man page by pressing Q on the keyboard.

TIP: Computers have come a long way since the man page system was created, and while reading a man page in the terminal is relatively easy for short and simple commands, it isn't ideal for more complex commands that can scroll through 100 or more screens. One neat trick (which we will revisit later in this chapter) is to use man -t command| open -f -a /Applications/Preview.app, which will open the entire man page of the command in Preview as a PDF file for immediate reading, printing, or saving. (The -t option converts the man page into a PostScript file, which you can then pipe into your Preview application, which converts the PostScript file into a PDF file as it opens it. Pipes are covered later.)

grep

The grep command searches through files or results for a specified string and then prints out the lines that contain a match. For example, using the preceding text file, you could print out all lines that contain “to” using the command grepto tomorrow. This is shown here:

Simba:Shakespeare scott$ ls
nothing  tomorrow
Simba:Shakespeare scott$ grep to tomorrow
Tomorrow, and tomorrow, and tomorrow,
Creeps in this petty pace from day to day
The way to dusty death. Out, out, brief candle!

NOTE: grep is actually a powerful tool that can be used with regular expressions, expressions that allow you to specify specific patterns that can be matched in large collections of text. Wildcards, described earlier in this chapter, are just a taste of the pattern-matching capabilities available in regular expressions.

ln

ln is the command-line utility for creating links. While there are different ways of linking files, what we are most concerned with are symbolic (aka soft) links (more commonly referred to as aliases, or shortcuts in Windows). To create a symbolic link, you use ln with the sswitch, followed by the name of the source file and then optionally the name of the linked file.

NOTE: As mentioned earlier, while an alias you create in the Finder and a symbolic (soft) link created with ln will generally appear and behave the same, they are not technically the same thing. There may be situation where a symbolic link will work where a Finder alias won't.

NOTE: ln by default creates a hard link, which is most likely not what you want, so it's important to remember the -s option. For the technically curious, a hard link essentially creates a new file that shares its data with another (the source). If you edit one, the data will change in the other. If you delete one, the other will still remain with all the data intact. A symbolic link, on the other hand (like an alias or shortcut), creates a special “path” file that always refers to the original. If this original is deleted, the path is broken unless a new file of the same name replaces the original. A big difference in use is that a symbolic link can refer to a directory or a file on a different file system, while a hard link cannot.

Let's look at ln in action:

Simba:Shakespeare scott$ ls
macbeth/ nothing
Simba:Shakespeare scott$ ls macbeth/
soliloquy4
Simba:Shakespeare scott$ ln -s macbeth/soliloquy4 tomorrow
Simba:Shakespeare scott$ ls -F
macbeth/    nothing     tomorrow@
Simba:Shakespeare scott$ cat tomorrow
Tomorrow, and tomorrow, and tomorrow,
Creeps in this petty pace from day to day
To the last syllable of recorded time,
And all our yesterdays have lighted fools
The way to dusty death. Out, out, brief candle!
Life's but a walking shadow, a poor player
That struts and frets his hour upon the stage
And then is heard no more:  it is a tale
Told by an idiot, full of sound and fury,
Signifying nothing.
who

The who command tells you who else is logged into the computer. Normally, this would just be you, since most personal computers would only allow one person to be logged in at a time (and this is how we still tend to use them). However, if you've turned on the Remote Login option on the Sharing control pane, it's possible for multiple users to actually be using one Mac OS system at a time. who also has a related command, whoami, which also tells you your username if you ever forget. (By the way, your Darwin username is the “short” username you picked when you created your account.)

Seeing these in action on your system isn't always that exciting:

Simba:~ scott$ who
scott    console  May 25 15:09
scott    ttys000  May 25 16:11
scott    ttys001  May 25 19:01
Simba:~ scott$ whoami
Scott

NOTE: In the who example, you may notice scott (that's me) is listed three times as being logged in. Why is that? Well, because I am logged in three times. First I'm logged into Mac OS X (that's the console listing). Then I have two terminal windows open, and Mac OS X considers each of those a separate login (ttys000 and ttys001).

NOTE: who is considered dangerous by many systems administrators who feel it's a potential security breach to disclose too much information about the system or its users; for this reason, on many servers, commands that provide information about users are either removed or disabled. Of course, the real cool (or if you're a systems administrator, real bad) command that is similar to who is finger. Historically, finger would allow you to find out all sorts of personal information about any user. Not only could you find information about users on your local machine, but you could actually “finger” anyone on any UNIX-type machine (and most other multi user systems of the day). The finger command still exists on some computers and is even installed on your Mac (go ahead, finger another user or yourself)—however, it's unlikely that you'll be able to find many machines on your network or on the Internet that will allow you to finger them or any of their users (for aforementioned security and even privacy fears). By default, Mac OS X will not allow any remote machine to finger you.

ps

ps allows you to view what processes are running at any given time on your system. By default, it shows limited information about all the services running from the terminal you are using (i.e., only the current Darwin process that you've started from your current terminal session). Until you really start digging into the power of Darwin, ps will likely just return your shell as your only process:

Simba:~ scott$ ps
  PID TTY           TIME CMD
  276 ttys000    0:00.12 -bash
  503 ttys001    0:00.01 –bash

The important pieces of information here are the PID (process ID) and the CMD (command). However, with a few options, ps can give you lots of information about every command running on your system. The most common options are -a, -j, and -x (so common, in fact, that you can issue them without the -). The ps command will most likely give you a long scrolling list of processes (the following list has had a significant chunk of the output removed for brevity):

Simba:~ scott$ ps -axj
USER             PID  PPID  PGID   SESS JOBC STAT   TT       TIME COMMAND
root               1     0     1 ffffff800beefe60    0 Ss     ??    0:16.08 /sbin/launchd
root              10     1    10 ffffff800beefba0    0 Ss     ??    0:01.45 /usr/libexec/
root              11     1    11 ffffff800beefa40    0 Ss     ??    0:00.80 /usr/libexec/
root              12     1    12 ffffff800beef8e0    0 Ss     ??    0:00.61 /usr/sbin/not
root              13     1    13 ffffff800beef780    0 Ss     ??    0:00.18 /usr/sbin/dis
root              14     1    14 ffffff800beef620    0 Ss     ??    0:01.80 /usr/libexec/
root              15     1    15 ffffff800beef4c0    0 Ss     ??    0:03.00 /System/Libra
root              16     1    16 ffffff800beef360    0 Ss     ??    0:00.33 /usr/sbin/sys

scott           1467  1466  1467 ffffff800beeede0    1 S    s001    0:00.03 -bash
root            1525  1467  1525 ffffff800beeede0    1 R+   s001    0:00.00 ps -axj

NOTE: ps aux is one of the most popular ps commands. However, the -u option in the version of ps that ships with Mac OS X performs a different task. That said, if you are in the habit of typing ps aux, it will still work. The -u will filter the output based on a specific user, while u (without the -) will give you the traditional u output. I'm one of those people who habitually uses aux (plus, I prefer its output to the j option), so I tend to use that in many of my examples.

This gives you much more information besides the PID and CMD (which is the full path, and as shown, is often truncated by the width of the terminal), including what user is responsible for the process. By default, the information is sorted by the process ID. If you want to filter this to show only what tasks a specific user is running, you can use the -u option. For example, if you just wanted to see how many processes you are personally responsible for, you could use the following:

Simba:~ scott$ ps -jxu scott
USER    PID  PPID  PGID   SESS JOBC STAT   TT       TIME COMMAND
scott   123     1   123 ffffff800beed7e0    0 Ss     ??    0:01.21 /sbin/launchd
scott   126   123   126 ffffff800beed7e0    1 S      ??    0:00.85 /usr/libexec/UserEvent
scott   141   123   141 ffffff800beed7e0    1 S      ??    0:23.54 /Applications/Mail.app
scott   142   123   142 ffffff800beed7e0    1 S      ??    0:38.68 /Applications/Twitter.
scott   144   123   144 ffffff800beed7e0    1 S      ??    0:51.21 /Applications/iTunes.a
scott   145   123   145 ffffff800beed7e0    1 S      ??    0:03.59 /System/Library/CoreSe
scott   165   123   165 ffffff800beed7e0    1 S      ??    0:01.01 /System/Library/Privat
scott   189   123   189 ffffff800beed7e0    1 SN     ??    0:00.02 /usr/libexec/warmd_age
scott   199   123   199 ffffff800beed7e0    1 S      ??    0:00.03 /System/Library/CoreSe
scott   202   123   202 ffffff800beed7e0    1 S      ??    0:00.18 /Applications/iTunes.a
scott   203   123   203 ffffff800beed7e0    1 S      ??    0:02.79 /System/Library/Servic
scott   414   145   145 ffffff800beed7e0    1 S      ??    0:01.66 /System/Library/CoreSe
scott   469   123   469 ffffff800beed7e0    1 S      ??    0:01.10 /System/Library/Image
scott   543   123   543 ffffff800beed7e0    1 S      ??    0:00.08 /usr/libexec/lsboxd
scott   582   144   144 ffffff800beed7e0    1 S      ??    0:00.30 /System/Library/Privat
scott  1320   123  1320 ffffff800beed7e0    1 SN     ??    0:00.58 /System/Library/Framew
scott  1414   123  1414 ffffff800beed7e0    1 S      ??    0:06.26 /Applications/Utilitie
scott  1436   281   281 ffffff800beed7e0    1 S      ??    0:00.86 /System/Library/Privat
scott  1528   123  1528 ffffff800beed7e0    1 S      ??    0:00.04 /System/Library/Framew
scott  1529     1  1529 ffffff800beee2e0    0 Us     ??    0:00.05 /usr/libexec/xpchelper
root   1466   271  1466 ffffff800beeede0    0 Ss   s001    0:00.03 login -pf scott
scott  1467  1466  1467 ffffff800beeede0    1 S    s001    0:00.03 -bash
root   1530  1467  1530 ffffff800beeede0    1 R+   s001    0:00.00 ps -jxu scott

NOTE: A similar command to ps is top. The primary difference between the two is that ps takes a snapshot of processes when you run the command, while top stays active and continually updates itself. The Activity Monitor application in the Utilities folder provides a nice GUI for the top command (and presents some additional information as well, including disk usage, memory usage, and CPU usage).

kill

kill is used to stop a specific process. This can be necessary if you have a task that is running amok and you can't figure out how else to stop it (perhaps you are attempting to write your own application or script, and it gets caught in a nasty loop).

To see this in action, you can intentionally create some nasty background tasks using the yes command, which you will then kill.

NOTE: The yes command by default prints out y indefinitely as fast as possible. If you want to find out just how hot your computer will get before a fan kicks in, you can open up a few terminal windows (or tabs) and run yes in each one. I'm not sure I'd recommend this if you are using a portable while it's sitting on your lap, though—you might not like the burning sensation it causes. To stop yes from running the “correct” way, just press Control-C.

To do this, first start running yes in the background twice, and then find out what the process ID of each yes process is and kill it:

Simba:~ scott$ yes > /dev/null &
[1] 1535
Simba:~ scott$ yes > /dev/null &
[2] 1536
Simba:~ scott$ ps u
USER    PID  %CPU %MEM      VSZ    RSS   TT  STAT STARTED      TIME COMMAND
scott  1535  99.3  0.0  2434788    420 s001  R     8:00AM   0:08.29 yes
scott  1536  97.8  0.0  2434788    420 s001  R     8:00AM   0:05.69 yes
scott  1467   0.0  0.0  2435492   1116 s001  S     7:40AM   0:00.03 -bash
Simba:~ scott$ kill 1535
[1]-  Terminated: 15          yes > /dev/null
Simba:~ scott$ kill 1536
[2]+  Terminated: 15          yes > /dev/null
Simba:~ scott$ ps u
USER    PID  %CPU %MEM      VSZ    RSS   TT  STAT STARTED      TIME COMMAND
scott  1467   0.0  0.0  2435492   1116 s001  S     7:40AM   0:00.04 -bash

There are a few things we should explain. The yes command you entered, yes > /dev/null &, takes the output of yes and redirects it to /dev/null, which is a special device in most UNIX systems that is a black hole of sorts. Everything sent to /dev/null just goes away. The > is the redirect command, and the & tells the terminal to run this in the background. We will cover background tasks and redirections later.

Finally, you may notice the ps command shows that one yes process is using 99.3 percent of the processor, and the other is using 97.8 percent, and these numbers don't seem to add up. The reason for this is that the %CPU shows the percentage for a single processor. Most Apple computers these days include at least two processing cores (including ours shown here), so in this case, one yes command is using 99.3 percent of one, while the other is using 97.8 percent of the other (your mileage may vary).

Occasionally, a simple kill still won't stop a process; in that event, you'll need to use kill -9 to stop the process. The -9 signal runs kill in Kill mode, which means that the process will force stop immediately.

NOTE: kill will attempt to gracefully terminate a process. In a way, this is similar to the Quit command in a Cocoa application (though without the “are you sure” dialogs and versions to save any unsaved work). kill -9 is more like force quitting an application. Using kill -9 will stop the process immediately without warning. This can have unexpected results if you accidently kill the wrong process, so like many tools covered here, handle with care.

less (more)

less is a pager, which allows you to scroll through large amounts of text that may normally scroll right by you in the terminal. You learned how pagers worked with the man command, which automatically runs in a pager (which by default in Mac OS X is actually less); however, sometimes it's useful to use a pager with other commands as well. For example, when you use the ps aux command, you are presented with lots of information scrolling right by; however, if you pipe the ps aux command into less, then you can scroll around the output just as you scrolled around the man pages. An example of this is the following:

Simba:~ scott$ ps aux | less

    RSS   TT  STAT STARTED      TIME COMMAND
 235440   ??  S     3:09PM  20:20.55 /Applications/Microsoft Office 2011/Microso
  62636   ??  S     4:11PM   0:26.50 /Applications/Utilities/Terminal.app/Conten
 144576   ??  Ss    3:09PM   6:19.10 /System/Library/Frameworks/ApplicationServi
   4200   ??  Ss    8:29AM   0:00.04 /usr/sbin/cupsd -l
   6812   ??  Ss    8:29AM   0:00.05 /usr/libexec/xpchelper
   2804   ??  Ss    8:28AM   0:00.03 /usr/sbin/ocspd
   1116 s001  S     7:40AM   0:00.04 -bash
   2820 s001  Ss    7:40AM   0:00.03 login -pf scott
  42604   ??  S     7:36AM   0:00.87 /System/Library/PrivateFrameworks/WebKit2.f
  27756   ??  S     7:18AM   0:06.27 /Applications/Utilities/Grapher.app/Content
  25644   ??  SN   11:16PM   0:00.69 /System/Library/Frameworks/CoreServices.fra
   8028   ??  S    10:23PM   0:00.31 /System/Library/PrivateFrameworks/MobileDev
   3760   ??  S     7:03PM   0:00.09 /usr/libexec/lsboxd
  42276   ??  S     7:03PM   0:07.48 /Applications/Preview.app/Contents/MacOS/Pr
608   ??  S     6:47PM   0:00.00 /usr/sbin/httpd -D FOREGROUND -D WEBSERVICE
   1668   ??  S     6:46PM   0:00.00 /usr/sbin/httpd -D FOREGROUND -D WEBSERVICE
   5348   ??  Ss    6:46PM   0:00.41 /usr/sbin/httpd -D FOREGROUND -D WEBSERVICE
  12732   ??  S     6:46PM   0:01.11 /System/Library/Image Capture/Support/Image
  32164   ??  S     6:12PM   0:01.80 /System/Library/CoreServices/Dock.app/Conte
  73716   ??  S     4:12PM   0:39.42 /Applications/Safari.app/Contents/MacOS/Saf
   1248   ??  S     3:11PM   0:00.04 /usr/sbin/distnoted agent
    800   ??  Ss    3:11PM   0:00.04 /sbin/launchd
:

Using the arrow keys, you can now scroll through your output, and when you are done, you can quit the pager and return to the prompt by pressing Q.

NOTE: Another older yet extremely popular pager was called more. Although more was very popular, it was lacking in many ways—for instance, it would only allow you to scroll down (e.g., you couldn't go back once you scrolled past something). Because of this, less has largely replaced more; however, for backward compatibility, the more command has been linked with less, so the more command still works (although it will actually run less).

find and where is

find and whereis are two commands that work very differently, yet are both used to the same ends: finding something in the Darwin file system.

find, by default, takes a path variable and presents a list of matches. Additionally, if a match is a directory, find will traverse that directory as well (find / will return every visible file on your hard drive!). Using regular expressions and wildcards can effectively narrow (or broaden) your search as needed. A simple find example may be something like this:

Simba:~ scott$ find "/Documents/Shakes*
/Users/scott/Documents/Shakespeare
/Users/scott/Documents/Shakespeare/macbeth
/Users/scott/Documents/Shakespeare/macbeth/soliloquy4
/Users/scott/Documents/Shakespeare/nothing
/Users/scott/Documents/Shakespeare/tomorrow

Listing directories is nothing new, but find becomes very useful with its ability to search for matches of specific file properties, the most popular being the name of the file. To use find this way, you give find the directory you wish to traverse, and then enter the -name option, followed by your search string. For example, if you were looking for the soliloquy in your Documents folder, you could use the following:

Simba:~ scott$ find "/Documents -name "sol*"
/Users/scott/Documents/Shakespeare/macbeth/soliloquy4

Other properties that you can use as search parameters for find include the file's owner and its group.

NOTE: When using find, it's best to have a good general idea of the location of the file you are looking for. While it's perfectly acceptable to do something like find / -name "sol*", find is not a fast command, so in addition to giving a number of false hits and warnings (mostly Permission Denied warnings from subdirectories that find isn't allowed to look in), it may take a relatively long time.

Unlike find, whereis is tailored specifically for finding executable files. It does this by specifically searching the common places where programs live (primarily the various bin and sbin directories for a specific program name you enter). For example, if you wanted to see where the whereis command is located, you could do this:

Simba:~ scott$ whereis whereis
/usr/bin/whereis

While this may seem trivial on a certain level, there are a couple of good reasons to use this. First, if you occasionally compile or install your own Darwin software (which we'll talk about in the next chapter), at some point you may end up with two copies of the same program, and whereis will help you find them so you can deal with it. Second, scripts written in languages like Perl, Python, or Ruby often want to know where the language executable is, and whereis provides a quick way to determine that.

NOTE: Two other commands worth mentioning here are locate and mdfind. locate searches its database, which contains a list of all publically readable files, for matches to your query, which makes it quite a bit faster than find. However, since the locate database is only occasionally updated, it's possible that what you are looking for isn't in the database. mdfind is a command unique to Mac OS X that actually searches on Spotlight's metadata. This makes it very fast and powerful—however, there is one minor setback in that Spotlight doesn't always index items until they are opened in the Finder. So, for example, our soliloquy4 text file may not show up in an mdfind search (or Spotlight search), at least until it is accessed by a non-command-line application. As such, mdfind wouldn't be a first choice for looking for something in the Darwin file system on the whole (however, it's an excellent choice if what you are looking for is visible in the Finder).

Pipes, Redirection, and Background Tasks

A few more things we should cover before we move on are the ability to pipe one command into another, the ability to redirect output (or input) to and from a command, and the ability to run tasks in the background. We've actually done each of these things in some of the preceding examples, yet as they are quite powerful, we'll give a bit more depth here.

Pipes

Piping one command into another is a great way to make even the simplest Darwin tools do powerful things. You saw this previously when you piped the ps command into the less command. The pipe symbol is the | (which is the tall line that lives above the on a normal US Mac keyboard). In practice, this takes the first command and sends the output into the second. For example, the ability to take commands that produce large amounts of output and pipe that content into a filter (like the grep command) can save lots of time and headaches.

Redirects

A redirect allows you to redirect the output of a command into a file, or alternatively direct the content of a file into a command. The symbols for redirection are < and >. A very simple use of a redirect is to create a text file using echo, like this:

Simba:~ scott$ echo "Hello my name is Scott" > name.txt
Simba:~ scott$ cat name.txt
Hello my name is Scott

The echo command normally would just print whatever you feed into it back to your terminal, but here we have redirected the output to name.txt (which may or may not have existed).

CAUTION: If you are redirecting data into an existing file using >, all the contents of that file will be replaced with the new data. So be very careful with this command.

If you want to redirect additional data into an existing file (rather than replace the content, which the > always does), you can use >> to append the new data to the old:

Simba:~ scott$ echo " Hello Scott" >> name.txt
Simba:~ scott$ cat name.txt
Hello my name is Scott
Hello Scott
Simba:~ scott$ echo "Ooops" > name.txt
Simba:~ scott$ cat name.txt
Ooops
Background Tasks

Any Darwin command can be issued to run in the background with the & symbol tacked onto the end of the command. This is particularly useful when you want to start a command that may take a long time to finish, or when running a task that you want to keep running indefinitely. For example, if you want to use the find command to find something with the name profile somewhere on your system, knowing that this may take some time, you may want to run it in the background. Here's an annotated example of this:

Simba:~ scott$ find / -name "profile" > found 2> found_err &
[l] 358

Here you start the find command in the background. You are redirecting the output to a file named found. The 2> found_err part of the command will redirect any error messages to a file named found_err. Without the 2> found_err, even though the command is running in the background, error messages would still spam the terminal (2> is a special redirect in Bash that only redirects error messages).

Simba:~ scott$ jobs
[l]+    Running   find / -name "profile"  >found 2>found_err &

The jobs command gives you a list of all of the background tasks and tells you their state (in this case, your only task is running).

Simba:~ scott$ fg
find / -name "profile" >found 2>found_err

The fg command (fg for foreground) brings forward the first running task (which for now is your only task). Since the command is running in the foreground, you can no longer use the terminal unless you pause the process. You can do this using the Control-Z key combo.

[l]+    Stopped   find / -name "profile"  >found 2>found_err

When you use Control-Z, you are giving the message that your task has stopped. You can now resume this task in the background using bg:

Simba:~ scott$ bg
[l]+ find / -name "profile"  >found 2>found_err &

While this task runs, let's start another background task:

Simba:~ scott$ (sleep 30; echo "done")&
[2]  359
Simba:~ scott$ jobs
[l]   Running                     find / -name "profile"  >found 2>found_err &
[2]+    Running                     ( sleep 30;  echo "done"  ) &

Now you have two jobs running in the background, your find command is still chugging along, and you have the new command (which will wait, or sleep, 30 seconds, and then run the echo "done" command). Notice that each job has been given a number. The find command is [1], and the sleep command is [2]. To pull the sleep command into the foreground, you must specify that you want job 2.

Simba:~ scott$ fg 2
( sleep 30;  echo "done"  )
done

Eventually, the sleep command will complete and echo “done” to the terminal. At this point, you can continue to use your terminal, and eventually you will get a message that your find command has completed.

[l]+    Exit 1                      find / -name "profile" >found 2>found_err
Simba:~ scott$ cat found
/dev/profile
/private/etc/profile
/System/Library/Tcl/8.4/tclx8.4/help/tcl/debug/profile
/System/Library/Tcl/8.5/tclx8.4/help/tcl/debug/profile
/usr/libexec/emacs/22.1/mac-apple-darwin/profile
/usr/share/devicemgr/backend/app/views/profile

Working As Root

In Darwin, the root user is synonymous with the administrator, superuser, or all-knowing, all-doing, grand poobah. Working as root is sort of like splitting the atom: great potential for good, great potential for total destruction. In the case of root, that which gets destroyed can vary from an important file to all of your data and the OS itself. Root has few boundaries and restrictions, and it can override all the security safeguards on the system. As such, you should never use it. Of course, sometime you may need to, or at least want to really, really badly.

CAUTION: With root comes lots of responsibility. Nothing short of a very powerful magnet sitting on your hard drive can mess up your system quite like a misplaced root command. As such, we cannot stress enough that root should be used sparingly and only when absolutely necessary.

So, when should you run a command as root? When there is no other way to run it. For example, when we ran our find command on the whole hard drive, we received a number of Permission Denied warnings (take a look at our found_err file). If we in fact wanted to search those protected files and directories, we would have to do so as root (or as the owner of the specific protected files or directories). Additionally, while you may be allowed to see and use many of the files and directories in Darwin, you won't be allowed to alter them or add new files to the directories. If you need to alter a configuration file, or install a new Darwin application in a specific location, or do one of many other related tasks, you will often have to do so as root.

When the time comes to run a command as root, one generally doesn't log out and log back in as root (which Apple goes to great lengths to make very difficult to do anyway). Instead, the recommended way is to utilize the sudo command.

sudo

The sudo command (which means substitute user do) allows selected users (only users with administrator privileges, by default) to run any other command as the root (or any other) user, as specified in the sudoers file (located at /etc/sudoers).

To run a command as root (which is sudo's default nature), merely precede the command with sudo—for example, if you wanted to manually run the weekly maintenance script, you would do so like this:

Simba:~ scott$ sudo periodic weekly
WARNING:  Improper use of the sudo command could lead to data loss or the deletion of important system files.  Please double-check your typing when using sudo. Type "man sudo" for more information.
To proceed,  enter your password,  or type Ctrl-C to abort.
Password:

As you can see, the first time you use sudo, you are given a stern warning about the dangers of using sudo, followed by a prompt for your password. Upon entering your password, the command will execute. The preceding warning will only appear the first time you use sudo—however, each time you use sudo, you will be prompted for a password, with one caveat: by default, sudo will save your password for a period of time (5 minutes is the default), so you won't have to reenter it for any subsequent sudo commands within that time period.

NOTE: The weekly maintenance scripts are among three script collections the system runs to maintain your computer. The other two are daily and monthly. These scripts are meant to run at their indicated intervals. However, this is based on the premise that your computer is always on! If you frequently turn off your computer (especially common for laptops), then it's possible that these scripts and their subsequent commands may never run. Thus, it may be beneficial to run these commands manually, as indicated previously, to help clean up and maintain your system. (The weekly and monthly scripts may take a few minutes to complete.)

By default, sudo allows root and any user in the admin group to utilize it. If a nonadmin user attempts to use sudo, instead of his or her chosen command being executed, that person will be presented with the following warning:

user is not in the sudoers file.    This incident will be reported.

To run a command as a user other than root, sudo offers the -u option, which you would use as follows:

sudo -u username command

On the slight chance that you really must execute a series of commands as another user and you'd like to maintain the user state for an extended period of time, sudo offers the -s option, which in effect starts the shell as the specified user. Since this command starts a shell as the specified user or root, no additional command is necessary. By default, this is the equivalent of using the older su command. If you must use this (and it's recommended that you don't), it's important to remember to quit (i.e., type exit) as soon as you are done—otherwise, you will remain in root state and are more likely to do something regrettable (or forget you are logged in as root and walk away from your computer for a cup of coffee or something and allow someone else to do something perhaps even more regrettable)!

NOTE: Before there was sudo, there was su (substitute user). Rather than taking a command, su just dropped you into a shell as root or the specified user. For whatever reason, many old-time UNIX users still swear by the su command, and while these are generally intelligent people who can perform amazing computer tasks in their sleep, their stubbornness in regard to su is misplaced. You shouldn't use su on the Mac (and yes, it is there). su was written in a time of relative innocence, when mail servers didn't require passwords and spam filters didn't exist, when virus protection wasn't a billion-dollar industry, and when god wasan appropriate (and sadly all too common) password for the root user. Anyway, those days are gone, and su just doesn't provide the features and, more importantly, the security that sudo provides (such as fine-grained per-user and per-group customizability, sophisticated checks on timestamps and files to assure that nobody has tampered with the file, and more).

The sudoers File

The sudo defaults are sensible and appropriate for most computer uses. However, for servers or other computers with many users, sudo can be coaxed into providing very specific, fine-grained privileges to individual users or groups. To do this requires editing the /etc/sudoers file. The catch is that to edit this file, you must have root privileges and you must use a special editor named visudo. visudo is really a special mode of the Vi editor—or more specifically, Vim, which stands for Vi improved, and is installed on Mac OS X in place of Vi. The easiest way to accomplish all this is to merely use the following:

Simba:~ scott$ sudo visudo
Password:

This immediately opens up the sudoers file to be edited (assuming you understand how Vi works, which if you don't right now, we will explain in the next section).

Sadly, a discussion of the many specific tweaks that can be made to this file would extend far beyond the confines of this book. However, typing man sudoers brings you to the man page for this particular file and explains in detail things like the extended Backus-Naur form, what exactly it means, and how to put it touse.

Editing Files

Editing files in Darwin is just one of those things that you'll eventually have to do to get the most out of it. For the most part, using a normal Mac OS X text editor like TextMate (€39, about $54), BBEdit ($49.99), Text Wrangler (free), or one of the many other text editors, may be your best bet—however, at times it may be handy or necessary to edit a file on the command line. Mac OS X ships with four command line–based text editors: Ed, Vim, Emacs, and Nano. Ed is the original text editor for UNIX, but many newer text editors have surpassed it in both usability and features. Despite this, it is still included in most UNIX distributions, since it has found a small niche within certain shell scripts. Each of the remaining three has its advantages, and what it comes down to for most people is a matter of taste and habit (i.e., once you start using one, it becomes a bit frustrating to use another, since they vary quite a bit).

NOTE: Since we mentioned some GUI text editors previously, it's worth noting that many of these come with a command-line executable as well, so that you may open any file in them from the command line. Specifically, BBEdit allows you to install the bbedit command-line executable, and TextMate allows you to install the tm command-line executable. Each of these will open the file in the GUI application when it's handy to do so from the command line. However, these applications won't help you much if you are accessing the machine remotely through a terminal window.

Vim

Vim is, as the name suggests, an improved clone of Vi (Visual Editor), which in turn is based on Ex, which is based on the aforementioned Ed (which was based on an even older text editor called QED). Vim can be baffling to people new to command-line editors because, like its predecessors, it is a dual-mode text editor. To get things done, you must switch between an insert or edit mode and a command mode. While this way of working with a text editor takes some getting used to, it's fairly easy once you get the knack of it. Also, Vim, Vi, or one of its clones is installed by default on almost every version of UNIX or Linux, so once you learn it, you can count on something like it to be installed on any UNIX (or UNIX-like) system you encounter.

NOTE: Vim specifically has a special third mode—visual mode—which can be toggled by typing v in command mode. Once in visual mode, you can move the cursor around normally—however, the text you move over will be selected. This mode is very handy for selecting text for precise copying and pasting.

When you launch Vim, you can either open an existing file, create a new file, or just jump into the editor without creating a file. The syntax is fairly straightforward:

vim [filename]

where filename is either an existing file or one you wish to create.

NOTE: In Mac OS X, vi, view, vimdiff, and ex all point to vim—however, they each cause Vim to exhibit different default behavior. vi and vim both launch in normal mode, view opens a file read-only, vimdiff allows you to open multiple files at the same time so that you can compare them, and ex opens Vim in ex mode (the :vi command returns you to normal mode).

Vim begins in command mode when opening a new or existing file; so, if you open the soliloquy file you've been working with in this chapter, you will be presented with the following:

Tomorrow, and tomorrow, and tomorrow,
Creeps in this petty pace from day to day
To the last syllable of recorded time,
And all our yesterdays have lighted fools
The way to dusty death. Out, out, brief candle!
Life's but a walking shadow, a poor player
That struts and frets his hour upon the stage
And then is heard no more: it is a tale
Told by an idiot, full of sound and fury,
Signifying nothing.
~
~
~
~
~
~
~
~
~
~
~
"soliloquy4"  10L,  409C

Some things to note here are the following:

  • The cursor begins on the first letter of the first line.
  • Lines on the screen beginning with ~ indicate that the line is empty (not just blank, but empty—in other words, it's not there).
  • The line at the very bottom of the screen is the informational display. Initially, it displays the name of the file, how many lines the file contains, and how many characters the file contains.

In command mode, the keys and key sequences have special meanings. For example, you can move your cursor around the text using the arrow keys, or the H, J, K, and L keys (old UNIX keyboards didn't all have arrow keys). If you are searching for a particular word (e.g., candle), you could use the search function, which is / followed by your search term. /candle followed by the Return key moves the cursor to the first letter of the first instance of candle that it finds. If you want to continue to search for the next occurrence of your search term, you can use an empty / and then press Return. In this particular case, since there is only one occurrence of candle, the informational line at the bottom tells you the search hit BOTTOM, continuing at TOP. If there were more occurrences of your search term, / would continue to search forward in your text for them. To search backward, replace the / with ?.

NOTE: Searching in Vim is case sensitive. Also, in its search, Vim has its own special characters—for example, the . character is a wildcard, so if you were to search for, say, the period at the end of a sentence, you would need to escape the . with a (backslash). Otherwise, it would match every character in the document.

To actually enter text, you need to enter insert mode. You can do this by typing i, which starts inserting at the point where your cursor is. Alternatively, typing I begins inserting text at the beginning of the line you are on, and o starts you at the beginning of a new line immediately below the line your cursor is on. In insert mode, you can type as you would normally. To exit insert mode and return to command mode, press the Esc key.

NOTE: If in doubt about which mode you are in, you can always press the Esc key to return to command mode (pressing Esc in command mode has no effect). Additionally, the informational line at the bottom will present you with a big, bold INSERT message when you are in insert mode.

When you are done editing your file, you can save it (while in command mode) using :w followed by Return if you wish to save it with the name that you initially opened the file with. Alternatively, you can use :w filename to save the file with a specific name.

TIP: To save some typing when saving files, you can use the % symbol to represent the initial file name. For example, if you opened a file named supertext, you could save it as supertext.new using :w %.new.

When your file is saved and you are ready to quit, you can quit using :q. Alternatively, you can save and quit in one shot using either :x, :wq, or (our favorite) ZZ.

NOTE: Occasionally you will find that Vim won't let you simply save a file or quit for certain reasons—most commonly when you wish to quit and your file is unsaved, or you are attempting to save a file that was opened as read-only. In either of these cases, the informational line will tell you why Vim is acting ornery and give you the option of overriding its warnings by appending ! to the end of your command. For example, to force quit an unsaved file, you need to use :q! rather than just:q.

Once you get used to working with two modes in Vim, the next thing you'll want to do is explore the features of the command mode. To help, Table 23-5 lists common commandmode keystrokes and what they accomplish (this is by no means a complete list).

Image

Image

Image

NOTE: Learning Vim takes some getting used to, but once you've grown comfortable with it you may find it indispensible. For those who love Vim but still enjoy a good graphical text editor, there is MacVim, a graphical Mac OS X native text editor built on Vim.

Emacs

Emacs (or GNU Emacs, as the faithful like to refer to it) is another popular text editor (perhaps it may be best described as a powerful runtime system with text-editing capabilities). Emacs can do wonderful things provided you take the time to learn a rather large number of mystical key combinations (and learning a little Lisp helps too). In fact, people who love and use Emacs (who really should have a name to describe them—like Trekkies or something, since they tend to share the same sort of devotion) won't settle for anything less.

Unlike Vim, Emacs is a single-mode text editor; so, in that way, it's probably similar to most GUI text editors you may have used. However, since it lacks a GUI, you can't use your mouse to access the fancy features. That's where the crazy keystrokes come into play. In general, these keystrokes use either the Control key or the Meta key plus some other key (in Emacs, the shorthand for this would be something like C-k for Control-K, or M-k for Meta-K). Usually, you would hold these keys at the same time. The gotcha here is that the Mac keyboard doesn't have a Meta key. You can fix this by selecting the “Use option as meta key” option in Terminal's Settings preferences (on the Keyboard tab, as shown in Figure 23-2).

TIP: If you don't wish to remap the option key to meta, you can also use the Esc key to carry out meta commands. Pressing the Esc key and then x, for example, is the same as M-x. Keep in mind this is Esc first, then x; rather than Esc+x at the same time.

Image

Figure 23-2. The “Use option as meta key” option is found in Terminal's Settings preferences.

As with Vi (described previously), you can either open an existing file, create a new file, or just start with a scratch buffer when you launch Emacs using the emacs [filename] command. Opening the soliloquy file produces the following output:

Tomorrow, and tomorrow, and tomorrow,
Creeps in this petty pace from day to day
To the last syllable of recorded time,
And all our yesterdays have lighted fools
The way to dusty death. Out, out, brief candle!
Life's but a walking shadow, a poor player
That struts and frets his hour upon the stage
And then is heard no more: it is a tale
Told by an idiot, full of sound and fury,
Signifying nothing.




-uu-:---Fl    soliloquy4          All Ll           (Fundamental)------------------

Once the file is open, it's immediately ready to edit. To move around in the file, you can use either the arrow keys or some C-n keystrokes (C-f, C-b, C-p, and C-n). The Delete key works as you would expect, and you can enter text at the cursor just by typing.

To save the file, you can either use C-x C-s to save the file with its existing name, or C-x C-w to save the file with a new file name. C-x C-c quits Emacs (it prompts you to save any changed files first). If you need to edit an additional file, you can use C-x C-f to open or create another file without quitting Emacs. Table 23-6 provides a handy list of a few common keystrokes and their effects.

Image

Image

NOTE: Emacs is big and powerful; we have just barely scratched the surface of all the features of Emacs here. For an example of how powerful (or perhaps how ridiculous) Emacs is, try this: Start Emacs and enter M-x doctor (press the Esc key and type “xdoctor”). Now, prepare yourself for a session of physiotherapy. Or for something else, try M-x tetris.

Nano

Nano is another handy command-line text editor in Mac OS X. What makes Nano special is that, compared to the others, it is relatively easy to figure out and use. The trade-off is that it lacks some of the more advanced (esoteric) features of Vim and Emacs, and while it's installed by default with Mac OS X (since Tiger), it's not as pervasive as Vim or Emacs.

NOTE: Nano is a clone of the Pico text editor, which is part of the fabulous command-line mail reader Pine. If you've used Pine in the past (or still do), you will find Nano immediately understandable. As an additional bonus, while many UNIX and Linux systems may not have Nano installed, it's just possible that they do have Pine installed, which will mean you may find Pico available where Nano isn't. Before Tiger, OS X included Pico, and today the pico command is still there, it's just aliased to nano.

One advantage of Nano is that the most common commands, along with the keystrokes to invoke them, are listed at the bottom of the screen (and the ones that aren't listed are easily looked up with the short yet concise built-in help). While the keystrokes may seem similar to Emacs in practice, the actual keys are different. Also, the common shorthand is different—while in Emacs, Control-X is represented as C-x, in Nano, it's represented as ^x (the ^ [caret] symbol means Control).

Opening files in Nano is the same as opening them in Vi or Emacs. Just type nano filename at the cursor, and it will open up. Once again, opening the soliloquy file, you would see the following:

Image

As you can see, at the top of the window Nano identifies the open file, and at the bottom it provides a list of common actions. The action list at the bottom will change based on circumstance—for example, when you go to save a file (using ^o), you will be prompted for the file name you wish to save your file as. The action list will also provide some other saving options (creating a backup, appending this file to another, etc.). With the short help file included with Nano, plus the adaptive action list shown, we're going to forgo the table of commands since it would largely beredundant.

File Permissions and Attributes

File permissions are a central concept found in UNIX systems. They allow one user to share files with everyone else on the system while still maintaining control of those files. The easiest way to view these permissions and attributes is with the ls -l command. For example, one line from an ls -l command may look like this:

-rw-r--r--     1 scott    scott       409 May 17 10:44 soliloquy4

The first string of 11 characters represents the permissions. Also of interest here are the file's owner (scott) and the file's group (also scott). The first ten characters are broken down as shown in Figure 23-3.

Image

Figure 23-3. Insert Figure Caption

NOTE: The 11th character is special and indicates additional file attributes or security applied to the file. We'll cover this in the “ACLs and Extended File Attributes” section.

The permissions are r, w, and x, signifying the ability to read, write, and execute, respectively (these are often referred to as bits). In the case of a directory, the execute bit signifies the ability to list files in the directory. The owner of any file can set these permissions as he or she sees fit using the chmod command. Additionally, the owner can reset the group to which the files belong to any other group the owner belongs to using the chgrp command.

The chmod command can be used one of two ways to set the permissions (also referred to as setting the mode): either literally or symbolically. The literal way is to specify the permissions as a string of numbers such as the following:

hmod nnnnfilename

where nnnn is the combined value of permissions based on Table 23-7.

Image

For example:

chmod 755 filename

would result in the filename having permissions -rwxr-xr-x.

The other, symbolic, way of setting permissions is to use chmod in the following way:

chmod  [u][g][o]+/-[r][w][x] filename

where u stands for owner, g stands for group, and o stands for other (everyone); followed by + (for adding) or - (for denying) permissions (r, w, and x).

For example, if you had a file with the permissions -rwxr-xr-x, but you wanted to allow anyone in its group to also write to the file, you could just use the following:

chmod g+w filename

This would effectively just add write permissions to the group for filename.

Suppose you create a file and then wish to give special permissions to a group of people. By default, any file you create will have both the owner and group listed as you. You can change the group file to any other group that you belong to using the chgrp command with the following syntax:

chgrp groupfilename

To find out what groups you belong to you (and thus what's available to you), you can use the id command, like so:

Simba:~ scott$ id
uid=501(scott) gid=20(staff)
groups=20(staff),402(com.apple.sharepoint.group.1),12(everyone),33(_appstore),61(localac
counts),79(_appserverusr),80(admin),81(_appserveradm),98(_lpadmin),100(_lpoperator),204(
_developer),401(com.apple.access_screensharing)

So in this case, if you want to allow anyone in the admin group to be able to write to your soliloquy4 file, you could do the following:

Simba:~/Documents/Shakespeare/macbeth scott$ chgrp admin soliloquy4
Simba:~/Documents/Shakespeare/macbeth scott$ ls -l

-rw-r--r-- 1 scott admin 409 May 17 10:44 soliloquy4
Simba:~/Documents/Shakespeare/macbeth scott$ chmod g+w soliloquy4
Simba:~/Documents/Shakespeare/macbeth scott$ ls -l

-rw-rw-r-- 1 scott admin 409 May 17 10:44 soliloquy4

ACLs and Extended File Attributes

ACLs (access control lists) and extended attributes were introduced to OS X in Tiger (OS X 10.4), but while they used to simply be an option available to those who wished to use them, they are now used by default.

NOTE: ACLs will only be available on your system locally if you are using the HFS+ file system. For network shares, they can be used over AFP and SMB/CIFS.

ACLs allow fine-grained control of a file's access far beyond UNIX's historical owner/group/everyone permissions. With ACLs you can control specific permissions for specific users or groups, and you can treat each user and group differently.

Specifically, each file on your system has one ACL, and each ACL may contain an ordered list of entries. Each entry sets specific permissions for a single user or group.

NOTE: If you have a user and a group with the same name, and you must differentiate these in an ACL, you may prefix the name with either user: or group: to specify which entity you are referring to.

Files with entries in their ACL will include a + in the 11th character in the permission listing when you use ls -l. If there are no ACL entries, but there are other file attributes for the given file, then the 11th character will contain an @. If there are no ACL entries or attributes, then the 11th character will be left off.

To view the ACL associated with a file, use the -e option with the ls command—for example, here's what one of our home directories looks like:

Simba:~ scott$ ls -le
total 32
drwx------+  5 scott  staff    170 May 15 09:28 Desktop
 0: group:everyone deny delete
drwx------+  9 scott  staff    306 May 25 18:11 Documents
 0: group:everyone deny delete
drwx------+ 14 scott  staff    476 May 25 16:18 Downloads
 0: group:everyone deny delete
drwx------@ 42 scott  staff   1428 May 15 18:29 Library
 0: group:everyone deny delete
drwx------+  3 scott  staff    102 Apr 28 18:42 Movies
 0: group:everyone deny delete
drwx------+  4 scott  staff    136 May  7 13:54 Music
 0: group:everyone deny delete
drwx------+  5 scott  staff    170 Apr 30 13:53 Pictures
 0: group:everyone deny delete
drwxr-xr-x+  5 scott  staff    170 Apr 28 18:42 Public

When you look at the ACLs attached to the default folders in your home directory, you'll see that they are set to deny everyone from deleting them. Don't be afraid to try it; if you try a rmdir, you'll get a Permission Denied warning, and if you try to drag the folders into the trash, you'll get a warning telling you that that directory can't be modified or deleted.

To view a file's attributes, use the -@ option with ls.

NOTE: Most of the file attributes are strictly there for application and Finder support. You can add your own attributes for whatever reason you want, but for the most part in OS X they are there to support the Finder.

To add entries to or delete entries from an ACL, you use the chmod command with +a (to add an entry) or -a (to remove an entry). When you are adding an entry, the new entry will be added to the ACL. To remove an entry, you need to specify the entry number using #n directives. Here are some examples of working with ACL entries:

Simba:macbeth scott$ ls -l
total 8
-rw-r--r--    1 scott    staff   401 Sep    7 07:47 soliloquy4
Simba:macbeth scott$ chmod +a "staff deny write,delete" soliloquy4
Simba:macbeth scott$ ls -le
total 8
-rw-r--r--+ 1 scott    staff   401 Sep    7 07:47 soliloquy4
0: group:staff deny write,delete
Simba:macbeth scott$ chmod +a "scott allow read,write,delete" soliloquy4
Simba:macbeth scott$ chmod +a "nobody deny read,write,delete" soliloquy4
Simba:macbeth scott$ ls -le
total 8
-rw-r--r--+ 1 scott    staff   401 Sep    7 07:47 soliloquy4
0:  user:nobody deny read,write,delete
1: group:staff deny write,delete
2:  user:scott allow read,write,delete
Simba:macbeth scott$ chmod -a# 1 soliloquy4
Simba:macbeth scott$ ls -le
total 8
-rw-r--r--+ 1 scott    staff   401 Sep    7 07:47 soliloquy4
0:  user:nobody deny read,write,delete
1:  user:scott allow read,write,delete

The types of actions you can control in ACLs depend on the type of file. The following actions are settable for any file:

  • delete
  • readattr
  • writeattr
  • readextattr
  • writeextattr
  • readsecurity
  • writesecurity
  • chown

The following actions are settable for folders/directories:

  • list
  • search
  • add_subdirectory
  • delete_child

Finally, the following are available for non-folder/directory items:

  • read
  • write
  • append
  • execute

More details about ACLs and controlling them are available in the chmod man page.

Customizing Terminal and the Shell

Once you start getting into using the command line, you may want to make a few tweaks to both the Terminal application and your shell environment to streamline how you work.

Terminal Setup

The Terminal application that Apple ships with Mac OS X is a nice, feature-rich application. It includes tabbed windows, which are handy for those who work with multiple shells or must access many remote terminals at the same time. It includes the ability to save different window settings that control the appearance and behavior of your terminal. The latest version that ships with Lion can be switched to full screen for a very retro-looking interface.

One of the first things you may want to do when working with Terminal is adjust how it looks and make a few other tweaks (such as remapping the Meta key if you are a big Emacs user). The options to control your terminal settings are listed under the Settings tab of Terminal's preferences (Figure 23-4).

Image

Figure 23-4.The Settings tab of Terminal's preferences

The Terminal Settings preferences provide a number of different possible terminal styles listed in the column on the left. In the preferences, you can set options for each setting individually using the five tabs: Text, Window, Shell, Keyboard, and Advanced.

The text settings control the font size, face, and colors. They also allow you to set the options for the terminal's cursor.

The Window tab allows you to set options for controlling the background color, title bar information, initial window size (set in character width and line height), and scrollback buffer.

The Shell tab allows you to set special shell startup commands, as well as options about what happens when you exit the shell or try to close the window while a shell is still running.

The Keyboard tab allows you to set up key bindings, and it lets you toggle the option to use the Option key as the Meta key.

The Advanced tab allows you to set a few other miscellaneous options pertaining to terminal emulation, bell actions, and text-encoding options for foreign languages.

The other main Terminal preference tabs include the Startup tab, which allows you to select the default settings to use when Terminal launches, as well as what type of shell Terminal should use upon launching; the Window Groups tab, which allows you to save the behavior of multiple Terminal windows together as a group; and the Encodings tab, which allows you to select which text encoding should be made available to Terminal's settings.

Setting Up Your Shell Environment

Every shell has what is referred to as an environment, which is basically made up of customized variables and commands that make the shell work the way you want it to. The Bash shell stores this info in a number of places. The variables that apply to everyone are stored in /etc/profile and /etc/bashrc. Additionally, you can make your own personal configurations to ~/.bashrc and ~/.bash_profile. As a general rule, things that affect your environment should go in the .bash_profile file, and things that affect the shell specifically should go in the .bashrc file.

NOTE: On many UNIX systems, things in the profile files get read when you log into a terminal, and things in the .bashrc files get read each time you launch a new shell. This isn't exactly how these things work in Mac OS X (or some newer *nix systems), but it's still nice to keep the content of each separate especially if you'd like to share your Mac OS X command-line environment with other *nix systems.

One common environmental variable that you may want to set is the $PATH variable. The $PATH variable describes where your shell will look for executables when you attempt to launch one from the command line. By default, your $PATH is set to include /bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, and /usr/X11/bin (in the /etc/profile file). However, if you begin to install new executables, or even write your own, you may find that you need to add additional directories to your $PATH. The syntax to add a directory to the $PATH is as follows:

export PATH=$PATH:/new/directory:/another/new/direcotry

NOTE: Whether you add your own paths before or after the default $PATH is significant, since each path in $PATH is checked in order. When you enter a command, the first match found will execute.

You can add as many directories as you need, separated by a colon. The $PATH at the beginning represents your existing path; without it, any of the default $PATH directories will be removed from your $PATH. To have your path updated each time you launch a shell, it's best just to put this info in your .bash_profile file. For example, the common .bash_profilefile may look like this:

###    .bash_profile    ###
#  a good place for environmental variables #

### $PATH ###

if [  -d ~/bin  ]  ;  then
   export PATH=~/bin:$PATH
fi

if [  -d /usr/local/bin ] ; then
   export PATH=/usr/local/bin:$PATH
fi

if [  -d /usr/local/mysql/bin  ]  ;  then
   export PATH=/usr/local/mysql/bin:$PATH
fi

if [  -d /opt/local/bin ]  ; then
   export PATH=/opt/local/bin:$PATH
Fi

if [  -d /opt/local/sbin ]  ; then
   export PATH=/opt/local/sbin:$PATH
fi

### include .bashrc if one exists ###
if [  -f ~/.bashrc  ];  then
.  ~/.bashrc
fi

Any line beginning with # is a comment. Here, some of the built-in scripting functionality is used to check if common executable directories exist—if they do, then they are automatically added to the $PATH.

The last part checks to see if the .bashrc file is present; if it is, then it is included as well.

The .bashrc files generally contain variables and commands that are specific to the shell. For example, the default /etc/bashrcfile sets the prompt variable. Other things that are generally included in the .bashrc files are common aliases and shell functions.

For example, a .bashrc file may contain the following:

###      .bashrc file     ###

#    This file is for shell-specific stuff           #
#    $PATH and other env variables should go in the  .bash_profile    #

### aliases ###

alias ls="ls -FG"
alias la="ls -FGA"
alias ll="ls -FGAl"

### functions ###

function pman() {
    man -t "${l}"| open -f -a /Applications/Preview.app/
}

Again, the lines that begin with # are comments.

Creating Commands with Aliases and Functions

The preceding sample .bashrc file shows a few aliases and a function. Essentially, these are both ways to create simple command-line commands that carry out more complex commands. In general, an alias provides a way of creating a shortened version of a single command, while a function creates a command out of an actual shell script that may consist of many commands and simple logic.

Aliases are incredibly handy when you find you are using the same commands over and over and want to simplify them; you can even use them to essentially overwrite the default behavior of a command. Take the first alias listed previously:

alias ls="ls -FG"

This command creates the ls alias from the ls -FG command, effectively overwriting ls so that it will, by default, provide colored output and the benefits of the -Fflag as well. The other two aliases in the previous .bashrcfile example also create aliases to other common ls options.

NOTE: You can create aliases at the command line using the alias command as well—however, if you don't save these to your .bashrc file, they will be gone once you exit that particular shell.

Functions, on the other hand, are more complex, as they are essentially simple shell scripts. Here's an example from the preceding.bashrc file:

function pman() {
    man -t "${l}" | open -f -a /Applications/Preview.app/
}

The first line defines pman as a function accessible from the command line, and everything between the curly braces defines what happens when we use the pman command. So, if you were to enter pman ls at the command line, the function would take the first argument, ls, and run man -t ls | open -f -a /Applications/Preview, app/, thus allowing you to open the man page of any command in the Preview application in one simplecommand.

Summary

Whew, there was lots of info in this chapter. While the aim wasn't to teach you everything about working with the command line (which would take an entire book in itself, and still leave out details), hopefully you now know enough to get around the command linecomfortably, and more importantly, have a good base to build upon where you see fit. We will be using the info in this chapter to build upon in various upcoming parts of this book, beginning with the next chapter, where we will take a quick look at adding to the abilities of Darwin by creating our own simple scripts and adding new programs from other sources.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset