The Bash shell comes with numerous special keys and clever shortcuts, which are designed to make your life at the keyboard faster and more efficient. Some of these control process execution, while others simply make it easier to enter your next command.
Many of the following keystrokes are used to interrupt the execution of a process:
Ctrl+C sends a SIGINT signal to the currently executing process, causing the process to be interrupted from whatever it was doing. This is useful when a program runs into a condition such as an infinite loop and you decide to terminate the execution of the command.
Ctrl+\ sends a SIGSEGV signal to the currently executing process. By default, the SIGSEGV signal causes a process to write the memory image of itself to the disk, often to a file called core . Some programmers find this useful because it allows them to interrupt execution of a (possibly faulty) program and then examine its memory image in the core file ”and thus determine what the program was doing.
At other times, Ctrl+\ comes in handy while attempting to terminate programs that do not terminate on Ctrl+C . Such programs may actually be handling the SIGINT signal for a legitimate purpose, but in a hang state, this prevents the graceful termination of the process.
Ctrl+Z is used to suspend a process that is currently executing. This causes the process to relinquish control, and the shell prompt is returned. This behavior is explored further in the Job Control section later in this chapter.
Ctrl+D is used to indicate the end of input. For example, if a program was coded to read in data until it encountered an end-of-file condition, Ctrl+D can be used to simulate the end-of-file when a user is typing in the input for the program.
The classic example for this is the shell itself. If you type Ctrl+D at the command prompt, the shell assumes that you have reached the end of your input into the shell, and that you have decided to exit. In fact, for the shell, Ctrl+D is synonymous with the exit command.
Ctrl+V does not have anything to do with process management, but it is used to input literal values of Ctrl keystrokes. For example, if you need to type the character corresponding to Ctrl+D , you would type Ctrl+V and Ctrl+D .
The erase keystrokes ( Ctrl+W and Ctrl+U ) come in handy when editing the command line (a topic covered in the next section of this chapter). Ctrl+W erases the entire word to the left of the cursor, and Ctrl+U erases everything to the left of the cursor.
The navigation keystrokes ( Ctrl+A and Ctrl+E ) move the cursor to the start and end of the command line, respectively.
Ctrl+R can be used to invoke an interactive search of the history.
The cursor keys are those that allow you to manipulate the shell s input cursor. Using the Up and Down arrow keys, it is possible to scroll through a history of commands that were executed, and execute them again (the Up arrow key allows you to scroll backward through the history of commands, while the Down arrow key allows you to scroll forward through them).
Often, you want to execute a command that is only slightly different from a previous command. In this case, you can use the Up and Down arrow keys to retrieve the previous command, and then use a number of different keys to position the cursor and edit the command:
You can use the Left and Right arrow keys to position the input cursor within the command.
As previously mentioned, you can also use Ctrl+A to jump to the start of the command line and Ctrl+E to jump to the end.
You can use the Backspace key to delete characters, and enter new characters simply by typing them in.
When you are finished, press Enter to execute the command.
While we re on the subject of the command history, it s worth taking a look at the history command. The history command prints a history of the commands executed, with a sequential number next to each command in the history:
$ history 1 ls -al 2 date 3 pwd 4 who 5 touch cellar/maze/labyrinth/passage/foo.txt $ !2
Tue Jan 14 23:03:43 2003 $
A previous command at position n can be referred to as !n . So, to execute the date command again, you could simply type in !2 (as shown in the example). While this does not sound like much of a saving, it is a great help when you re working with very lengthy commands.
Here are some more useful shortcuts that can be used to invoke commands from the history:
The double exclamation mark ( !! ) has the effect of telling Bash to execute the last command once again. For example, if you execute the date command, and then enter !! , the date command will be executed again:
$ date Tue Jan 14 23:03:43 2003 $ !! Tue Jan 14 23:03:45 2003
An exclamation mark ( ! ), followed by some text, has the effect of executing the command from the shell s history that begins with that text and has the closest match to it. For example, given the history of five commands shown previously, the command !p would result in the pwd command being executed. If there was another command starting with the letter p in the history (for example, ps ), you would have to supply a closer match (such as !pw ) to execute the pwd command.
The !$ shortcut allows you to reuse the last argument of the previous command. For example, in the fifth command of the previously listed history, a file named foo.txt has been created under a deep directory structure. Suppose that you wanted to remove it immediately after; you could do this by typing in rm !$ as the next command:
$ touch cellar/maze/labyrinth/passage/foo.txt $ rm !$ rm cellar/maze/labyrinth/passage/foo.txt $
The Bash shell automatically substitutes !$ with the last argument of the previous command, so that the rm command shown with the gray background here is equivalent to the one shown with the white background after it.
An extension of the !$ shortcut is the !* shortcut. This simply translates into all of the arguments of the previous command. For example, the following commands create two files and then delete them again:
$ touch foo.txt bar.txt $ rm !* rm foo.txt bar.txt $
As mentioned previously, the Ctrl+R keystroke can be used to invoke an interactive search of the history. After typing in Ctrl+R , you could type in the minimal set of characters that uniquely match the start of a command in history:
$ history 1 ls -al 2 date 3 pwd 4 ps 5 touch cellar/maze/labyrinth/passage/foo.txt $ Ctrl-R (reverse-i-search)'pw': pwd
The act of typing in the letters pw uniquely matches the pwd command, successfully distinguishing it from the ps command, which also starts with the letter p .
The previous section looked at shortcuts that help to quickly ferret out commands from the history and execute them as such or modify them before executing them. This section explores shortcuts to reference commands and objects in the filesystem. The Tab key is your ally in this quest.
To appreciate command completion, you first need to understand how, when you type in a command at the prompt, the shell knows where to look for that command on the filesystem. For example, when you type in the date command, the shell seems to know that you are referring to the date program residing in the /bin directory.
In fact, when Bash starts up, it consults a startup script . The startup script contains an environment variable called PATH , the value of which is a list of directories that contain programs. Then, when you type in a command and press Enter , Bash automatically searches the directories in this list, in an attempt to locate a program whose name is the same as the command you typed in.
We ll discuss environment variables and startup variables more as we progress through the chapter.
If you type in just the first few letters of a command at the Bash prompt, and then press the Tab key, Bash starts searching the PATH (the list of directories) for a unique command that matches the starting letters that you typed in:
If it finds an exact match, it completes the command automatically:
$ da<Tab> date Tue Jan 14 23:03:43 2003
If it finds more than one match, it beeps and awaits user input. If you press the Tab key again, it displays a list of all matches. At this point, you need to type in more letters and hit the Tab key again to narrow down the search to the command that you are interested in:
$ ta<Tab> tac tack tail talk tar tal<Tab> $ talk
If Bash does not find a single match, it simply beeps every time you press the Tab key. So, going by the previous cases, if Bash beeps twice in a row with no choices to display, it is trying to tell you that it found no match for what you typed in.
Apart from automatically matching and completing the commands to be executed, Bash also features automatic completion of the names of files and directories. For example, the following creates two directories called cistern and cavern , and a file called water.txt . Then, the third command moves the file into the cistern directory using the mv command, by specifying just enough of the cistern directory name followed by the Tab key:
$ mkdir cistern cavern $ touch water.txt $ mv water.txt ci<Tab>stern
The Tab keystroke causes Bash to look for a unique match and, in this case, it finds one ”the cistern directory ”and thus completes the directory name.
The same rule applies to files, too. The first command here changes the working directory to cistern , and the second removes the file water.txt (which you specify simply by typing w and letting Tab and the shell do the rest):
$ cd ci<Tab>stern $ rm w<Tab>ater.txt