Опубликован: 06.08.2012 | Уровень: специалист | Доступ: платный
Лекция 7:

The tools of the trade

Command history and other editing functions

Nowadays, most shells supply a command history function and additional functionality for editing it. We'll take a brief look at these features here—for more details see the man pages for your shell.

Shell command line editing has been through a number of evolutionary phases. The original Bourne shell supplied no command line editing at all, though the version supplied with FreeBSD gives you many of the editing features of more modern shells. Still, it's unlikely that you'll want to use the Bourne shell as your shell: bash, ksh, and zsh are all compatible with the Bourne shell, but they also supply better command line editing.

The next phase of command line editing was introduced with the C shell, csh.By modern standards, it's also rather pitiful. It's described in the csh man page if you really want to know. About the only part that is still useful is the ability to repeat a previous command with the !! construct. Modern shells supply command line editing that resembles the editors vi or Emacs. In bash, sh, ksh, and zsh you can make the choice by entering:

$ set -o emacs   for Emacs-style editing
$ set -o vi      for vi-style editing

In tcsh, the corresponding commands are:

% bind emacs
% bind vi

Normally you put one of these commands in your startup file.

In Emacs mode, you enter the commands simply by typing them in. In vi mode, you have to press ESC first. Table 7-5 shows an overview of the more typical Emacs-style commands in bash. Many other shells supply similar editing support.

As the name suggests, the Emacs editor understands the same editing characters. It also understands many more commands than are shown here. In addition, many X-based commands, including web browsers, understand some of these characters.

Таблица 7.5. Emacs editing characters
Key Function
Ctrl-A Move to the beginning of the line.
LeftArrow Move to previous character on line.
Ctrl-B Move to previous character on line (alternative).
Ctrl-D Delete the character under the cursor. Be careful with this character: it’s also the shell’s end-of-file character, so if you enter it on an empty line, it stops your shell and logs you out.
Ctrl-E Move to the end of the line.
RightArrow Move to next character on line.
Ctrl-F Move to next character on line (alternative).
Ctrl-K Erase the rest of the line. The contents are saved to a ring buffer of erased text and can be restored, possibly elsewhere, with Ctrl-Y.
Ctrl-L Erase screen contents (shell) or redraw window (Emacs).
DownArrow Move to next input line.
Ctrl-N Move to next input line (alternative).
UpArrow Move to previous input line.
Ctrl-P Move to previous input line (alternative).
Ctrl-R Incremental search backward for text.
Ctrl-S Incremental search forward for text.
Ctrl-T Transpose the character under the cursor with the character before the cursor.
Ctrl-Y Insert previously erased with Ctrl-K or Alt-D.
Ctrl-_ Undo the last command.
Alt-C Capitalize the following word.
Alt-D Delete the following word.
Alt-F Move forward one word
Alt-L Convert the following word to lower case.
Alt-T Transpose the word before the cursor with the one after it.
Alt-U Convert the following word to upper case.
Ctrl-X Ctrl-S Save file (Emacs only).
Ctrl-X Ctrl-C Exit the Emacs editor.

You'll note a number of alternatives to the cursor keys. There are two reasons for them: firstly, the shell and Emacs must work on systems without arrow keys on the keyboard. The second reason is not immediately obvious: if you're a touch-typer, it's easier to type Ctrl-P than take your hands away from the main keyboard and look for the arrow key. The arrows are good for beginners, but if you get used to the control keys, you'll never miss the arrow keys.

File name completion

As we have seen, UNIX file names can be much longer than traditional Microsoft names, and it becomes a problem to type them correctly. To address this problem, newer shells provide file name completion. In Emacs mode, you typically type in part of the name, then press the Tab key. The shell checks which file names begin with the characters you typed. If there is only one, it puts in the missing characters for you. If there are none, it beeps (rings the "terminal bell"). If there are more than one, it puts in as many letters as are common to all the file names, and then beeps. For example, if I have a directory docco in my home directory, I might enter:

=== grog@freebie (/dev/ttyp4) ~ 14 -> cd docco/
=== grog@freebie (/dev/ttyp4) "/docco 15 -> ls freebsd.faq   freebsd.fbc freeware
=== grog@freebie (/dev/ttyp4) "/docco 16 -> emacs freebeepbsd.fbeepaq

Remember that my input is in constant width bold font, and the shell's output is in constant width font. On the first line, I entered the characters cd doc followed by a Tab character, and the shell completed with the text co/. On the last line, I entered the characters emacs f and a Tab. In this case, the shell determined that there was more than one file name that started like this, so it added the letters ree and rang the bell. I entered the letter b and pressed Tab again, and the shell added the letters sd.f and beeped again. Finally, Iadded the letters aq to complete the file name freebsd.faq.

Command line completion in vi mode is similar: instead of pressing Tab, you press ESC twice.

Shell startup files

As we saw above, there are a lot of ways to customize your shell. It would be inconvenient to have to set them every time, so all shells provide a means to set them automatically when you login. Nearly every shell has its own startup file. Table 7-6 gives an overview.

Таблица 7.6. Shell startup files
Shell startup file
bash .profile, then .bashrc
csh .login on login, always .cshrc
sh .profile
tcsh .login on login, always .tcshc, .cshrc if .tcshrc not found

These files are shell scripts—in other words, straight shell commands. listing 7-1 shows a typical .bashrc file to set the environment variables we discussed.

umask 022
export BLOCKSIZE=1024     #for df
export CVSROCT=/src/ncvs
export EDITCR=/opt/bin/emacs
export MANPATH=/usr/share/man:/usr/local/man
export MCZILLA_HOME=/usr/local/netscape
export PAGER=less
export PATH=/usr/bin:/usr/local/bin:/usr/sbin:/bin:/sbin:/usr/X11R6/bin
PS1="=== \u@\h rtty1) \w \# -> "
PS2="\u@\h \w \! ++ "
export SHELL=/usr/local/bin/bash
export TAPE=/dev/nsa0     #note non-rewinding as standard 
if [ "$TERM" = "" ]; then
  export TERM=xterm
fi
if [ "$DISPLAY" = "" ]; then
  export DISPLAY=:0
fi
/usr/games/fortune       # print a fortune cookie
Листинг 7.1. Minimal .bashrc file

It would be tedious for every user to put settings in their private initialization files, so the shells also read a system-wide default file. For the Bourne shell family, it is /etc/profile, while the C shell family has three files: /etc/csh.login to be executed on login, /etc/csh.cshrc to be executed when a newshell is started after you login, and /etc/csh.logout to be executed when you stop a shell. The start files are executed before the corresponding individual files.

In addition, login classes (page 571) offer another method of setting environment variables at a global level.

Бехзод Сайфуллаев
Бехзод Сайфуллаев
Узбекистан, Бухара, Бухарский институт высоких технологий, 2013
Василь Остапенко
Василь Остапенко
Россия