Hack 49 More Terminal Tricks and Tips

figs/expert.giffigs/hack49.gif

So many commands, so little time to learn them all. Here are a few more command-line tips and tricks that you are sure to find useful.

With a plethora of commands and various ways in which to combine them and string them together, you can do virtually unlimited things on the command line. Here are a few more tips and tricks you'll find useful while working your way through some of the hacks in this book.

Of course, this crash course combined with [Hack #48] barely scratches the surface of the powerful Unix operating system. For a more in-depth treatment, we highly recommend Unix Power Tools (http://www.oreilly.com/catalog/upt3/).

49.1 Customizing Your Terminal

Over time, you will no doubt be bored with Terminal's plain black-on-white settings. Here are some tips for adding some spice to your Terminal windows.

Longtime Unix users would be familiar with the green-on-black settings. Those were the days when dumb terminals ruled and a color monitor was more a luxury than a necessity. In Mac OS X, you can change the color of your Terminal window to mimic the good old days.

To change the color of your Terminal window, click on Terminal Window Settings..., as shown in Figure 5-6.

Figure 5-6. Changing the appearance of your Terminal window
figs/xh_0506.gif

The Terminal Inspector window will appear (see Figure 5-7); it's from here that you may make various changes to your Terminal window configuration.

Figure 5-7. Changing the color of a Terminal window
figs/xh_0507.gif

If you simply want all Terminal windows to adopt the settings you have just created, select File Use Settings As Defaults.

To save your modified settings without applying them globally, select File Save As... to save them to a .term preference file, as shown in Figure 5-8.

Figure 5-8. Saving Terminal settings to a .term file
figs/xh_0508.gif

You can create multiple .term files representing various different configurations. To open a Terminal window with a particular setting, select it from File Library, select File Open..., and choose the appropriate .term file, or drag it to your Dock and click it whenever you want a Terminal window of that type. By default, .term files are saved to your Library/Application Support/Terminal directory.

You can even have a particular .term file run a specific command when it opens. Open a .term file in your favorite plain-text editor [Hack #51] and look for this:

... <key>ExecutionString</key> <string></string> ...

Alter the value of the <string> element to be whatever you'd like run on the command line when the Terminal window opens. I have a shell script for port-forwarding my mail [Hack #70], called mailforward.sh, which I run every time I come online after being off for a while simply by double-clicking my mailforward.term file in my Dock. That .term file's ExecutionString looks like this:

... <key>ExecutionString</key> <string>~/bin/mailforward.sh</string> ...

49.2 Switching Terminal Windows

Often, you may have many Terminal windows lying about. Switching between them using mouse clicks can be more trouble than it's worth. Thankfully, there are a few keyboard shortcuts. Press figs/command.gif-1 to switch to the first window, figs/command.gif-2 for the second, and so on. If you want to loop through the open Terminal windows, type figs/command.gif-right arrow or figs/command.gif-left arrow for forward and backward, respectively.

49.3 Learning from History

At times, you may want to reuse the commands that you've typed previously, especially if a command has lengthy options and parameters; you wouldn't want to type everything again, now would you? You can always use the up and down arrow keys to navigate previously used commands, but when you're reaching back a number of commands ago, there's a better way than wearing away your fingerprint hitting that up arrow repeatedly. Use the history command to display the list of previously executed commands:

% history
1 11:34 cal 2003
2 11:34 ls -al
3 11:34 clear
4 11:34 man open
5 11:34 history

The history command even lists the time at which the command was executed. To reuse a particular command, type ! (exclamation point or "bang" in hacker-speak), followed by the number listed alongside the command you want to reuse, then press the Return key. Here, for example, I run the second item in the list:

% !2
ls -al
{a long-format listing of all files in the local directory}

If you have a long history list ? I always do ? you can also use the first few letters of the command line instead of the command number, like so:

% !ls
ls -al
{a long-format listing of all files in the local directory}

This can, however, be dangerous and unpredictable if you end up running something that started with the same letters but wasn't quite the same command you had in mind. Think about running rm * (remove all files in the current directory) when you think you're running rm notes.txt (remove the notes.txt file). You can get history to show you what it thinks you mean by adding a :p to the end of the history reference, whether it be by number or first few characters:

% !ls:p
ls -al
% !ls
ls -al 
{a long-format listing of all files in the local directory}

You can also use :p to recall and then slightly alter an earlier command by pressing the up arrow right afterward, editing the command line, and pressing Return:

% !rm:p
rm a.txt b.txt c.txt
{hit the Up arrow}
% rm a.txt b.txt d.txt

49.4 Listing All the Commands

The man (manual) command [Hack #48] allows you to check for the usage of a command. But how do you know which commands are available to you in the first place? You can take a gander at the entire list of available commands by pressing Control-X, Control-D.

49.5 Changing Permissions with chmod

The Unix command chmod (change mode) alters permissions on files and directories, allowing you to fine-tune access control and protect files from unauthorized users or accidental deletion (hey, it happens!).

Permissions are perhaps best explained by example. First, create a new directory named my_folder:

% mkdir my_folder

Change into the newly created directory and list all the files therein; there shouldn't be anything aside from . (this directory) and .. (the parent directory):

% cd my_folder
% ls -al
total 0
drwxr-xr-x 2 weimengl staff 68 Dec 13 09:31 .
drwxr-xr-x 18 weimengl staff 612 Dec 13 09:31 ..

Next, create a new text file. One of the simplest ways to create a quick test file is by echoing some text to it, literally sending some text toward the file, indicating toward using the > redirection operator:

% echo "Some text" > file1.txt

Take a look at the default permissions for the file we just created; they're at the left margin associated with file1.txt:

% ls -l
total 8
-rw-r--r-- 1 weimengl staff 10 Dec 13 09:33 file1.txt

Permissions come in three sets of three: owner, group, and world, each with an associated read, write, and execute permission. Our file1.txt is readable and writeable (rw-) by the owner (that's you), readable (r--) by the group (that's anyone who's in the staff group along with you), and readable (r--) by anyone else.

We will concern ourselves only with owner permissions at this point. Let's change the permissions on file1.txt so that it is not writable by you, thus protecting it against accidental overwriting:

% chmod u-w file1.txt 

The parameter u-w tells chmod to remove the write permission from the user (owner). To confirm, take another look:

% ls -l
total 8
-r--r--r-- 1 weimengl staff 10 Dec 13 09:33 file1.txt

Try deleting the file. You'll be prompted to override the permission settings. If you weren't the owner, however, you'd simply be denied permission altogether:

% rm file1.txt
override r--r--r-- weimengl/staff for file1.txt? 

Try appending some text to the file (>> means append rather than write to). Since you've denied yourself write permission, you'll fail:

% echo "Some more text" >> file1.txt file1.txt: Permission denied.

To grant yourself write permission again, do the inverse of the previous chmod using +, like so:

% chmod u+w file1.txt

Now let's return to the home directory and examine the permission settings for the my_folder directory:

% cd ~
% ls -l
total 40
...
drwxr-xr-x 3 weimengl staff 102 Dec 13 09:39 myFolder
...

Try removing the execute (x) permission from the directory for yourself, the owner. Then try visiting it again using cd:

% chmod u-x my_folder
% cd my_folder
my_folder: Permission denied.

Why are you locked out? Directories are special files requiring execute permissions before allowing you into or across their borders. Since you don't have execute permission, you're barred.

Put back the execute permission while at the same time removing write permission and cd into my_folder again:

% chmod u+x my_folder
% chmod u-w my_folder
% cd my_folder

All appears back to normal; you should have landed just fine inside my_folder. Try to create another file in your now unwritable directory:

% echo "Some text" > file2.txt file2.txt: Permission denied.

As you might have guessed, while you can visit the folder thanks to executable permission, you can't alter it in any way without write permission. You can't create, move, or delete anything. You can, however, still edit file1.txt, since a file's permissions take precedence when dealing directly with it.

There is also a way to refer to permissions numerically (e.g., chmod 755 script.cgi), but we'll leave that to a more advanced Unix text.

49.6 Changing Owner and Group with chown and chgrp

This is all well and good, given that all the files in your directory (presumably) belong to you. But what of files that aren't yours yet need some dealing with? That's where chown (change owner) and chgrp (change group) come in.

Take a quick look at the document directory for your onboard Apache web server [Hack #88]:

% cd /Library/WebServer/Documents/
% ls -al
total 376
drwxrwxr-x 38 root admin 1292 Dec 13 00:24 .
drwxrwxr-x 5 root admin 170 Dec 10 17:39 ..
-rw-rw-r-- 1 root admin 3726 Jul 27 14:31 PoweredByMacOSx.gif
-rw-rw-r-- 1 root admin 31958 Jul 27 14:31 PoweredByMacOSxLarge.gif
-rw-rw-r-- 1 root admin 2326 Apr 14 1999 apache_pb.gif
-rw-rw-r-- 1 root admin 1884 Oct 17 2001 index.html.ca
...
-rw-rw-r-- 1 root admin 1062 Jun 19 18:23 index.html.zh
lrwxrwxr-x 1 root admin 38 Dec 13 00:24 manual -> /Library/Documentation/Services/apache

Notice that, by default, they're all owned by the root user [Hack #50] and admin group. I'm not root, but I am an admin user, as shown by the whoami and groups commands:

% whoami
weimengl
% groups
staff admin

Given the permissions on the files and the directory they're in, I should be able to create, edit, move, and remove anything I need to in order to tend this machine's web site. But what of the nonadministrative users I have helping me? There has to be some way to give them ownership of some of these files. And there must be some way to claim ownership of a file and block admin access to it ? except by the root user, of course.

The chown command does just that. Perhaps you'd like to take ownership of index.html.ca and horde write permission:

% sudo chown weimengl index.html.ca
Password:
% chmod g-w index.html.ca
% ls -l index.html.ca
-rw-r--r-- 1 weimengl admin 1884 Oct 17 2001 index.html.ca

Now the file is owned by you, and nobody but you has write permission to it.

Since you can't simultaneously be the owner of the file as it stands and the owner you're about to give it, chown requires becoming the root user for a moment [Hack #50].

Perhaps you want to give write permission to everyone working on the web site. You could change permissions so that all the files are world writable (chmod o+w), but that's generally regarded as bad form. Instead, you could simply change the group ownership (chgrp ) of the particular files you'd like them to all share, in this case, all the index.html files:

% sudo chgrp staff index.html*
Password:
% ls -al index.html.*
-rw-rw-r-- 1 root staff 1884 Oct 17 2001 index.html.ca
...
-rw-rw-r-- 1 root staff 1062 Jun 19 18:23 index.html.zh

Being pedantic, it's actually best to create a new group, webadmin, for example, into which to put all those folks working on the site. This is better than giving write access to anyone you happen to let log in to your machine. But, since this was meant as a quick demonstration of chgrp, we glossed over those details.

If you have some reason to change both owner and group at the same time, you can combine these actions into one command: chown owner.group.

49.7 Counting Files

Unlike Windows (or DOS, in particular), the ls command in Unix does not display the total number of files displayed. Consider the following example:

[Apple-s-Computer:~] weimenglee% ls -l
total 2200
drwx------ 12 weimengl staff    408 Dec 12 11:35 Desktop
drwx------ 6  weimengl staff    204 Dec 11 20:17 Documents
drwx------ 24 weimengl staff    816 Dec  9 21:09 Library
drwx------ 3  weimengl staff    102 Dec  9 17:08 Movies
drwx------ 3  weimengl staff    102 Dec  9 17:08 Music
drwx------ 4  weimengl staff    136 Dec  9 20:36 Pictures
drwxr-xr-x 4  weimengl staff    136 Dec 11 08:53 Public
drwxr-xr-x 5  weimengl staff    170 Dec 11 09:05 Sites
-rw-r--r-- 1  weimengl staff 380235 Dec 11 15:17 foo.pdf
-rw-r--r-- 1  weimengl staff 412280 Dec 11 15:48 image.pdf
-rw-r--r-- 1  weimengl staff 328970 Dec 11 15:38 test.pdf

For directories with few files, this generally is not a problem. But at times you need to know the total number of files and you do not want to wade through a long list of files.

To count the files, you can use the | (pipe) character and the wc (word count) command with the -l option to count the number of lines:

% ls -l | wc -l
12 

Note that the actual file count should be 11, but the count includes the line total 2200 and so is off by 1.

And if you want to count the number of directories, you can use the grep command. The grep command looks over incoming text and prints out lines that match the specified pattern. To find all lines starting with d, you'd use ^d as the pattern, the ^ signifying the beginning of a line:

% ls -l | grep ^d | wc -l
8 

And if you want only regular files, you'd look for lines starting with -:

% ls -l | grep ^- | wc -l
3

If you'd like to see a listing of only PDF files, you can again use a pattern, this time grepping for the characters at the end of the line. The end-of-line pattern indicator is $:

% ls -l | grep pdf$ | wc -l
3

It found foo.pdf, image.pdf, and test.pdf, as it should have. One could more easily have used * (star or splat) as a stand-in for the bits of the files we didn't know and simply listed everything ending in .pdf like so:

% ls *.pdf | wc -l
3

49.8 Displaying a Calendar

Need to check the date for last Wednesday? Here is a quick way to do it in the Terminal. Use the cal (calendar) command:

% cal
December 2002
 S  M Tu  W Th  F  S
 1  2  3  4  5  6  7
 8  9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

Without any parameters, cal will display the calendar for the current month. You can also display the calendar for the entire year. cal supports years 1 to 9999:

% cal 2003
2003 

January               February               March        
 S  M Tu  W Th  F  S   S  M Tu  W Th  F  S   S  M Tu  W Th  F  S
          1  2  3  4                     1                     1
 5  6  7  8  9 10 11   2  3  4  5  6  7  8   2  3  4  5  6  7  8
12 13 14 15 16 17 18   9 10 11 12 13 14 15   9 10 11 12 13 14 15
19 20 21 22 23 24 25  16 17 18 19 20 21 22  16 17 18 19 20 21 22
26 27 28 29 30 31     23 24 25 26 27 28     23 24 25 26 27 28 29
                                            30 31
...

October               November              December      
 S  M Tu  W Th  F  S   S  M Tu  W Th  F  S   S  M Tu  W Th  F  S
          1  2  3  4                     1      1  2  3  4  5  6
 5  6  7  8  9 10 11   2  3  4  5  6  7  8   7  8  9 10 11 12 13
12 13 14 15 16 17 18   9 10 11 12 13 14 15  14 15 16 17 18 19 20
19 20 21 22 23 24 25  16 17 18 19 20 21 22  21 22 23 24 25 26 27
26 27 28 29 30 31     23 24 25 26 27 28 29  28 29 30 31
                      30

You can also opt to display a particular month in a particular year:

% cal 1 2003
January 2003
 S  M Tu  W Th  F  S
          1  2  3  4
 5  6  7  8  9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Or, you can display the date in Julian format:

% cal -j 2003
2003 

January                     February          
  S   M  Tu   W  Th   F   S    S   M  Tu   W  Th   F   S
              1   2   3   4                           32
  5   6   7   8   9  10  11   33  34  35  36  37  38  39
 12  13  14  15  16  17  18   40  41  42  43  44  45  46
 19  20  21  22  23  24  25   47  48  49  50  51  52  53
 26  27  28  29  30  31       54  55  56  57  58  59

...

November                     December          
  S   M  Tu   W  Th   F   S    S   M  Tu   W  Th   F   S
                        305      335 336 337 338 339 340
306 307 308 309 310 311 312  341 342 343 344 345 346 347
313 314 315 316 317 318 319  348 349 350 351 352 353 354
320 321 322 323 324 325 326  355 356 357 358 359 360 361
327 328 329 330 331 332 333  362 363 364 365
334

?Wei-Meng Lee



     
    ASPTreeView.com
     
    Evaluation has НЩВіexpired.
    Info...