9.14. The TC Shell Command Line
9.14.1 The Command Line and Exit Status
After logging in, the TC shell displays its primary prompt, by default a > symbol. The shell is your command interpreter. When the shell is running interactively, it reads commands from the terminal and breaks the command line into words. A command line consists of one or more words (or tokens) separated by whitespace (blanks and/or tabs) and terminated by a newline, generated by pressing the Enter key. The first word is the command, and subsequent words are the command's options and/or arguments. The command may be a Linux executable program such as ls or pwd, an alias, a built-in command such as cd or jobs, or a shell script. The command may contain special characters, called metacharacters, that the shell must interpret while parsing the command line. If the last character in the command line is a backslash, followed by a newline, the line can be continued to the next line.
Exit Status and the printexitvalue Variable
After a command or program terminates, it returns an exit status to the parent process. The exit status is a number between 0 and 255. By convention, when a program exits, if the status returned is 0, the program was successful in its execution. When the exit status is nonzero, then it failed in some way. If the program terminated abnormally, then 0200 is added to the status. Built-in commands that fail return an exit status of 1; otherwise, they return a status of 0.
The tcsh status variable or ? variable is set to the value of the exit status of the last command that was executed. Success or failure of a program is determined by the programmer who wrote the program. By setting the tcsh variable, printexitvalue, any time a program exits with a value other than 0, its status will automatically be printed.
Example 9.73.
1 > grep "ellie" /etc/passwd
ellie:GgMyBsSJavd16s:501:40:E Quigley:/home/jody/ellie:/bin/tcsh
2 > echo $status or echo $?
0
3 > grep "nicky" /etc/passwd
4 > echo $status
1
5 > grep "scott" /etc/passsswd
grep: /etc/passsswd: No such file or directory
6 > echo $status
2
7 > set printexitvalue
> grep "XXX" /etc/passwd
Exit 1
>
EXPLANATION
The grep program searches for the pattern "ellie" in the /etc/passwd file and is successful. The line from /etc/passwd is displayed. The status variable is set to the exit value of the grep command; 0 indicates success. The ? variable also holds the exit status. This is the variable used by the bash and ksh shells for checking exit status. (It is not used by csh.) The grep program cannot find user nicky in the /etc/passwd file. The grep program cannot find the pattern, so it returns an exit status of 1. The grep fails because the file /etc/passsswd cannot be opened. Grep cannot find the file, so it returns an exit status of 2. The special tcsh variable printexitvalue is set. It will automatically print the exit value of any command that exits with a nonzero value.
9.14.2 TC Shell Command-Line History
The history mechanism is built into the TC shell. It keeps in memory a sequentially numbered list of the commands, called events, that you have typed at the command line. As well as the number of the history event, it also keeps track of the time the event was entered at the terminal. When the shell reads a command from the terminal, it breaks the command line into words (using whitespace to designate a word break), saves the line to the history list, parses it, and then executes it. The previous command typed is always saved. You can recall a command at any time from the history list and re-execute it without retyping the command. During a login session, the commands you type are appended to the history list until you exit, at which time they can be saved in a file in your home directory, called .history. The terms history list and history file can be somewhat confusing. The history list consists of the command lines currently held in the shell's memory. The history file, normally called .history, is the text file where those commands are saved for future use. The built-in variable, savehist, saves the history list to the .history file when you log out, and loads its contents into memory when you start up. (See –S and –L options to the history command in Table 9.10.) The history built-in command displays the history list. It supports a number of arguments to control how the history is displayed.
Table 9.10. The history Command and OptionsOption | Meaning |
---|
-c | Clears the history list in memory, not the history file | -h | Prints history list without numbers | -L [filename] | Appends history file (.history or filename) to the history list | -M [filename] | Like -L, except merges contents of history file with current history list | n | n is a number, for example, history 5, controlling the number of lines displayed | -r | Prints history list in reverse | -S [filename] | Saves history list to .history or filename if given | -T | Prints timestamps in comment form |
Although the default name for the history file is .history, its name can be changed by assigning an alternative name to the built-in shell variable, histfile. The history shell variable is set to a number specifying how many commands to display and the histdup variable can be set so that duplicate entries are not added to the history file.
Example 9.74.
(The Command Line)
> history
1 17:12 cd
2 17:13 ls
3 17:13 more /etc/fstab
4 17:24 /etc/mount
5 17:54 sort index
6 17:56 vi index
EXPLANATION
The history list displays the last commands that were typed at the command line. Each event in the list is preceded with a number (called an event number) and the time that it was entered at the command line.
The history Variable
The TC shell history variable can be set to the number of events from the history list that will be displayed on the terminal. Normally, this is set in the /etc/.cshrc or ~/.tcshrc file, the user's initialization file. It is set to 100 by default. You can also provide an optional second value for the history variable to control the way the history is formatted. This value uses the same formatting sequences as the prompt variable. (See Table 9.10.) The default format string for history is %h\t%T\t%R\n.
Example 9.75.
1 set history=1000
2 set history= ( 1000 '%B%h %R\n' )
3 history
136 history
137 set history = ( 1000 '%B%h %R\n' )
138 history
139
140 pwd
141 cal
141 pwd
142 cd
EXPLANATION
The last 1,000 commands typed at the terminal can be displayed on the screen by typing the history command. The last 1,000 commands typed at the terminal are displayed. The format string causes the history list to be displayed in bold text (%B) first with the event number (%h), then a space, and finally the command that was typed (%R) at the command line followed by a newline (\n). When you type history, the new format is shown. This is only a selected section of the real history list.
Saving History and the savehist Variable
To save history events across logins, set the savehist variable. This variable is normally set in the .tcshrc file, the user's initialization file. If the first value assigned to savehist is a number, it cannot exceed the number set in the history variable, if the history variable is set. If the second value is set to merge, the history list is merged with the existing history file instead of replacing it. It is sorted by timestamp, and the most recent events saved.
Example 9.76.
1 set savehist
2 set savehist = 1000
3 set savehist = 1000 merge
EXPLANATION
The commands from the history list are saved in the history file and will be at the top of the history list the next time you log in. The history file is replaced with the last 1,000 commands from the history list, and saved. It will be displayed when you next log in. Rather than replacing the existing history file, the current history list will be merged with the existing history file when you log out, and loaded into memory after you log in.
Displaying History
The history command displays the events in the history list. The history command also has options that control the number of events and the format of the events that will be displayed. The numbering of events does not necessarily start at one. If you have 100 commands on the history list, and you have set the history variable to 25, you will only see the last 25 commands saved.
Example 9.77.
1 > set history = 10
2 > history
1 ls
2 vi file1
3 df
4 ps –eaf
5 history
6 more /etc/passwd
7 cd
8 echo $USER
9 set
10 ls
EXPLANATION
The history variable is set to 10. Only the last 10 lines of the history list will be displayed, even if there are many more. The last 10 events from the history are displayed. Each command is numbered.
Example 9.78.
1 > history –h # print without line numbers
ls
vi file1
df
ps –eaf
history
more /etc/passwd
cd
echo $USER
set
history –n
2 > history -c
EXPLANATION
With the h option, the history list is displayed without line numbers. With the c option, the history list is cleared.
Example 9.79.
> history –r # print the history list in reverse
11 history –r
10 history –h
9 set
8 echo $USER
7 cd
6 more /etc/passwd
5 history
4 ps –eaf
3 df
2 vi file1
1 ls
EXPLANATION
The history list is displayed in reverse order.
Example 9.80.
> history 5 # prints the last 5 events on the history list
7 echo $USER
8 cd
9 set
10 history –n
11 history 5
EXPLANATION
The last five commands on the history list are displayed.
Accessing Commands from the History File
There are several ways to access and repeat commands from the history list. A nice new feature is included with tcsh: You can use the arrow keys with history. They allow you to scroll up and down the history list, and to move left and right across lines, editing as you go; you can use a mechanism called history substitution to re-execute and fix spelling mistakes; or you can use the built-in emacs or vi editors to retrieve, edit, and execute previous commands. We'll step through each of these procedures and then you can choose whatever way works best for you.
The Arrow Keys To access commands from the history list, you can use the arrow keys on the keyboard to move up and down through the history list, and from left to right. You can edit any of the lines in the history list by using the standard keys for deleting, backspacing, and so on. As soon as you have edited the line, pressing the carriage return (Enter key) will cause the command line to re-execute. You can also use standard emacs or vi commands to edit the history list. (See Table 9.13 on page 475 and Table 9.14 on page 476.) The arrow keys behave the same way for both the vi and emacs keybindings. (See Table 9.11.) Table 9.13. vi CommandsCommand | Function |
---|
Moving Through the History File | Esc K or + | Move up the history list | Esc J or - | Move down the history list | G | Move to first line in history file | 5G | Move to fifth command in history file | /string | Search upward through history file | ? | String search downward through history file | Moving Around on a Line | h | Move left on a line | l | Move right on a line | b | Move backward a word | e or w | Move forward a word | ^ or 0 | Move to beginning of first character on the line | $ | Move to end of line | Editing with vi | a A | Append text | i I | Insert text | dd dw x | Delete text into a buffer (line, word, or character) | cc C | Change text | u U | Undo | yy Y | Yank (copy a line into buffer) | p P | Put yanked or deleted line down below or above the line | r R | Replace a letter or any amount of text on a line |
Table 9.14. emacs CommandsCommand | Function |
---|
Ctrl-P | Move up history file | Ctrl-N | Move down history file | Esc < | Move to first line of history file | Esc > | Move to last line of history file | Ctrl-B | Move backward one character | Ctrl-R | Search backward for string | Esc B | Move back one word | Ctrl-F | Move forward one character | Esc F | Move forward one word | Ctrl-A | Move to the beginning of the line | Ctrl-E | Move to the end of the line | Esc < | Move to the first line of the history file | Esc > | Move to the last line of the history file | Editing with emacs | Ctrl-U | Delete the line | Ctrl-Y | Put the line back | Ctrl-K | Delete from cursor to the end line | Ctrl-D | Delete a letter | Esc D | Delete one word forward | Esc H | Delete one word backward | Esc (space) | Set a mark at cursor position | Ctrl-X Ctrl-X | Exchange cursor and mark | Ctrl-P Ctrl-Y | Push region from cursor to mark into a buffer (Ctrl-P) and put it down (Ctrl-Y) |
Table 9.11. The Arrow KeysKey | What It Does |
---|
| Up arrow moves up the history list | | Down arrow moves down the history list | | Right arrow moves cursor to the right of history command | | Left arrow moves cursor to the left of history command |
Re-executing and Bang! Bang! To re-execute a command from the history list, use the exclamation point (bang) to start history substitution. The exclamation point can begin anywhere on the line and can be escaped with a backslash. If the ! is followed by a space, tab, or newline, it will not be interpreted. There are a number of ways to use history substitution to designate what part of the history list you want to redo. (See Table 9.12 on page 474.) If you type two exclamation points (!!), the last command is re-executed. If you type the exclamation point followed by a number, the number is associated with the command from the history list and the command is executed. If you type an exclamation point and a letter, the last command that started with that letter is executed. The caret (^) is also used as a shortcut method for editing the previous command. Table 9.12. Substitution and HistoryEvent Designators | Meaning |
---|
! | Indicates the start of history substitution | !! | Re-executes the previous command | !N | Re-executes the Nth command from the history list | !-N | Re-executes the Nth command back from present command | !string | Re-executes the last command starting with string | !?string? | Re-executes the last command containing string | !?string?% | Re-executes the most recent command-line argument from the history list containing string | !^ | Uses the first argument of the last history command in the current command line | !* | Uses all of the arguments from the last history command in the current command line | !$ | Uses the last argument from the last history command in the current command line | !! string | Appends string to the previous command and executes | !N string | Appends string to Nth command in history list and executes | !N:s/old/new/ | In previous Nth command, substitutes the first occurrence of old string with new string | !N:gs/old/new/ | In previous Nth command, globally substitutes old string with new string | ^old^new^ | In last history command, substitutes old string with new string | command !N:wn | Executes current command appending an argument (wn) from the Nth previous command; wn is a number starting at 0, 1, 2, . . . designating the number of the word from the previous command; word 0 is the command itself, and 1 is its first argument, and so on | !N:p | Puts the command at the bottom of the history list and prints it, but doesn't execute it |
After history substitution is performed, the history list is updated with the results of the substitution shown in the command. For example, if you type !! the last command will be re-executed and saved in the history list in its expanded form. If you want the last command to be added to the history list in its literal form; that is, !!, then set the histlit shell variable.
Example 9.81.
1 > date
Mon Feb 8 12:27:35 PST 2004
2 > !!
date
Mon Aug 10 12:28:25 PST 2004
3 > !3
date
Mon Aug 10 12:29:26 PST 2004
4 > !d
date
Mon Aug 10 12:30:09 PST 2004
5 > dare
dare: Command not found.
6 > ^r^t
date
Mon Apr 10 16:15:25 PDT 2004
7 > history
1 16:16 ls
2 16:16 date
3 16:17 date
4 16:18 date
5 16:18 dare
6 16:18 date
8 > set histlit
9 > history
1 16:18 ls
2 16:19 date
3 16:19 !!
4 16:20 !3
5 16:21 dare
6 16:21 ^r^t
EXPLANATION
The date command is executed at the command line. The history list is updated. This is the last command on the list. The !! (bang bang) gets the last command from the history list; the command is re-executed. The third command on the history list is re-executed. The last command on the history list that started with the letter d is re-executed. The carets are used to substitute letters from the last command on the history list. The first occurrence of an r is replaced with a t. The history command displays the history list, after history substitution has been performed. By setting histlit, the shell will perform history substitution, but will put the literal command typed on the history list; that is, just as it was typed. When histlit is set, the output of the history command shows what commands were literally typed before history substitution took place. (This is just a demo; the history numbers are not accurate.)
Example 9.82.
1 % cat file1 file2 file3
<Contents of files displayed here>
> vi !:1
vi file1
2 > cat file1 file2 file3
<Contents of file, file2, and file3 are displayed here>
> ls !:2
ls file2
file2
3 > cat file1 file2 file3
> ls !:3
ls file3
file3
4 > echo a b c
a b c
> echo !$
echo c
c
5 > echo a b c
a b c
> echo !^
echo a
a
6 > echo a b c
a b c
> echo !*
echo a b c
a b c
7 > !!:p
echo a b c
EXPLANATION
The cat command displays the contents of file1 to the screen. The history list is updated. The command line is broken into words, starting with word number zero. If the word number is preceded by a colon, that word can be extracted from the history list. The !:1 notation means: get the first argument from the last command on the history list and replace it in the command string. The first argument from the last command is file1. (Word 0 is the command itself.) The !:2 is replaced with the second argument of the last command, file2, and given as an argument to ls. File2 is printed. (File2 is the third word.) ls !:3 reads: go to the last command on the history list and get the fourth word (words start at zero) and pass it to the ls command as an argument. (File3 is the fourth word.) The bang (!) with the dollar sign ($) refers to the last argument of the last command on the history list. The last argument is c. The caret (^) represents the first argument after the command. The bang (!) with the ^ refers to the first argument of the last command on the history list. The first argument of the last command is a. The asterisk (*) represents all arguments after the command. The bang (!) with the * refers to all of the arguments of the last command on the history list. The last command from the history list is printed but not executed. The history list is updated. You could now perform caret substitutions on that line.
9.14.3 The Built-In Command-Line Editors
The command line can be edited by using the same type of key sequences that you use in either the emacs or vi editors. You can use editor commands to scroll up and down the history list. Once the command is found, it can be edited, and by pressing the Enter key, re-executed. When the shell was compiled, it was given a default set of keybindings for the emacs editor.
The bindkey Built-In Command
The built-in bindkey command is used to select either vi or emacs for command-line editing and to list and set keybindings for the respective editors. To use vi as your command-line editor, use bindkey with the –v option:
bindkey -v
and to go back to emacs, type
bindkey -e
To see a list of editor commands and a short description of wh
|