Command the Command Line

Part II - Getting Your Bearings

Process Management I

After invoking a program and starting a process, there are a number of reasons you may want to move on before the process is complete. However, these processes generally maintain control of the terminal window until they terminate. In this section, we'll cover the most common cases of long-running processes and how you can regain control of the terminal in each.

Case #1: "I want to cancel this work"

vm$ find / -name nemo
​

Occasionally, you may mis-type a command and accidentally start a process that takes a very long time to complete. In this example, we're using the find command to search for all files named "nemo" in the entire file system. We most likely intended to limit our search to a more specific location (e.g. our $HOME directory).

We could simply open a new terminal window and re-enter the command. But in the mean time, we will have a useless terminal window open, busy doing unnecessary work.

Instead, we'll send a "signal" to the active process.

vm$ find / -name nemo
​^C
vm$ 

By holding the Ctrl key and then processing the c key, we can send a special "SIGINT" signal to the current process. Most applications (including find) will respond to this by terminating.

Now that we've cancelled that work, we can use the same terminal window to re-enter the correct command.

Case #2: "I'm done entering data"

vm$ sort
​murdock, matt
​stark, tony
​rogers, steve
​banner, bruce
​parker, peter
​romanov, natalya
​

Many applications that accept files as arguments can also operate on "standard input." In these cases, instead of reading the contents of the file, the program accepts input from the terminal directly. sort is one such application.

The problem is that we need some way to signal that we are done. If we try the same approach as the previous use case and press Ctrl+C, the process will terminate without giving us results. In this case, we need a way to signal that we are done entering input and would like the program to continue its work.

vm$ sort
​murdock, matt
​stark, tony
​rogers, steve
​banner, bruce
​parker, peter
​romanova, natasha
​^D
banner, bruce
murdock, matt
parker, peter
rogers, steve
romanova, natasha
stark, tony
vm$ 

By holding the Ctrl key and pressing the d key, we are sending the "end of file" character. This is a little counter intuitive; just remember that these programs are written to accept files as input, and the "end of file" character makes more sense in that context.

Most shells interpret this as an indication that the user is done entering commands, so this will close the terminal window if you enter it on the command line directly.

Case #3: "I'd like to do other things while this completes."

vm$ find / -name nemo
​

You will sometimes intentionally run processes that you expect to take a long time to complete. In these cases, you may like to get other additional work done while you wait. You could open another terminal window, but this can be inefficient (and may clutter up your desktop environment).

vm$ find / -name nemo
​^Z
[1]+  Stopped                 find / -name nemo
vm$ 

By holding the Ctrl key and then processing the z key, we can send a special "SIGTSTP" signal to the current process. This causes the process to stop (but not exit) and release the terminal.

We can go back to entering more commands, but the "stopped" command will wait in the background forever. We can get it to continue working without tying up the terminal again, but doing that will take a new command.

vm$ jobs
[1]+  Stopped                 find / -name nemo
vm$ bg 1
[1]+ find / -name nemo &
vm$ jobs
[1]+  Running                 find / -name nemo &
vm$ 

The find process is known as a "job," and we can verify that it is still present (but "stopped") with the jobs command. If we had used Ctrl+z with other commands, then they'd be listed here, too.

While a process is "stopped", it is no longer doing any work. We can use the bg command to set it running again. There can be any number of jobs running at once, so we need to refer to the job we want by ts "job ID" (1 in this case).

vm$ jobs
[1]+  Running                 find / -name nemo &
vm$ fg 1
​

Finally, if we want to return to the job before it is finished, we can use the fg command (again, referencing it by "job ID").

In Review

Exercise

tac is a program that collects input and prints it out in reverse. It's like cat but backwards (which might explain the silly name).

vm$ tac
​first
​second
​third
​fourth
​^D
fourth
third
second
first
vm$ 

Let's use tac to practice with managing multiple concurrent processes.

We'll be sending signals to the tac command in this exercise, but it's easy to make a mistake and send the signal to the shell instead. That may cause you to log out of the virtual machine. Remember: the vm$ prompt lets you know that you're executing commands inside the virtual machine. If you see a different prompt, then you have likely logged out. You can reconnect to the virtual machine using the vagrant ssh command. For a refresher on this, refer back to Chapter 3 - Using Vagrant.

  1. Run tac and type 1 followed by a new line, then 2 followed by a new line, and finally 3 followed by a new line. Now put the tac process into the background. What is the process's "job" ID?

  2. Run tac again. This time, type a followed by a new line, then b followed by a new line, and finally c followed by a new line. Now put this second tac process into the background. What is the process's "job" ID?

  3. Bring the first tac process into the foreground. (You'll need your answer to question number 1 to do this.)

  4. Type 4 followed by a new line. If you send a "SIGINT" signal to this process, what do you expect to see printed to the terminal? Send a SIGINT signal. What was printed?

  5. Bring the second tac process into the foreground. (You'll need your answer to question number 2 to do this).

  6. Type d followed by a new line. If you send the "end of file" character to this process, what do you expect to see printed to the terminal? Send the "end of file" character to the process. What was printed?

Solution

  1. To "background" a process, hold the Ctrl key and then press the z key. The terminal will print out a message telling you that the process is stopped; the job ID is the number enclosed in square braces, e.g. [1].

  2. See above. The job ID for this process should be different than the ID assigned to the first one (most likely one greater), e.g. [2].

  3. Type fg, followed by a space, followed by the job ID from step one, and then finally Enter/Return.

  4. To send the "SIGINT" signal, hold the Ctrl key and then press the c key. After receiving this signal, the process should exit without printing anything to the screen.

  5. Type fg followed by a space, followed by the job ID from step two, and then finally Enter/Return.

  6. To send the "end of file" character, hold the Ctrl key and then press the d key. After receiving this character, the tac program should print out each line you entered in reverse. Remember that this is the same process you created in step 2, so the complete output will include the lines you entered back then:

    d
    c
    b
    a