Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding @gvwilson's original lesson from #25

Open
wants to merge 4 commits into
base: gh-pages
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 162 additions & 1 deletion 06-job-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,169 @@ title: Extra Unix Shell Material
subtitle: Job control
minutes: 5
---

> ## Learning Objectives {.objectives}
>
> * FIX ME

FIX ME
Our next topic is how to control programs *once they're running*. This
is called [job control](glossary.html#job-control), and while it's less
important today than it was back in the Dark Ages, it is coming back
into its own as more people begin to leverage the power of computer
networks.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That last half sentence is rather vague and isn't adding much. What has this to do with networks?


When we talk about controlling programs, what we really mean is
controlling *processes*. As we said earlier, a process is just a program
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the just

that's in memory and executing. Some of the processes on your computer
are yours: they're running programs you explicitly asked for, like your
web browser. Many others belong to the operating system that manages
your computer for you, or, if you're on a shared machine, to other
users. You can use the `ps` command to list them, just as you use `ls`
to list files and directories:

~~~{.input}
$ ps
~~~
~~~{.output}
PID PPID PGID TTY UID STIME COMMAND
2152 1 2152 con 1000 13:19:07 /usr/bin/bash
2276 2152 2276 con 1000 14:53:48 /usr/bin/ps
~~~

Every process has a unique process id (PID). Remember, this is a
property of the process, not of the program that process is executing:
if you are running three instances of your browser at once, each will
have its own process ID.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth noting that PIDs fall into a certain range and can "overflow" i.e. the same PID can refer to different processes over the uptime of the OS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note added - may or may not be technically accurate. :P

The second column in this listing, PPID, shows the ID of each process's
parent. Every process on a computer is spawned by another, which is its
parent (except, of course, for the bootstrap process that runs
automatically when the computer starts up).

The third column (labelled PGID) is the ID of the *process group* this
process belongs to. We won't discuss process groups in this lecture, but
they're often used to manage sets of related processes. Column 4 shows
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Break paragraph before Column 4

the ID of the terminal this process is running in. Once upon a time,
this really would have been a terminal connected to a central timeshared
computer. It isn't as important these days, except that if a process is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could slot in a sentence like

On modern unix systems this terminal is virtual and the process (normally) gets its input from and sends its output and error messages to this terminal.

The following sentence can then be shortened to

If a process is ...

a system service, such as a network monitor, `ps` will display a
question mark for its terminal, since it doesn't actually have one.

Column 5 is more interesting: it's the user ID of the user this process
is being run by. This is the user ID the computer uses when checking
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

computer -> operating system

permissions: the process is allowed to access exactly the same things as
the user, no more, no less.

Finally, Column 6 shows when the process started running, and Column 7
shows what program the process is executing. Your version of `ps` may
show more or fewer columns, or may show them in a different order, but
the same information is generally available everywhere.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a sentence:

If needed, the list of columns and their order can be customized by passing command line options to ps.


The shell provides several commands for stopping, pausing, and resuming
processes. To see them in action, let's run our `analyze` program on our
latest data files. After a few minutes go by, we realize that this is
going to take a while to finish. Being impatient, we kill the process by
typing Control-C. This stops the currently-executing program right away.
Any results it had calculated, but not written to disk, are lost.

~~~{.input}
$ ./analyze results*.dat
~~~

~~~
...a few minutes pass...
^C
~~~

Let's run that same command again, with an ampersand `&` at the end of
the line to tell the shell we want it to run in the
[background](glossary.html#background):

~~~{.input}
$ ./analyze results*.dat &
~~~

When we do this, the shell launches the program as before. Instead of
leaving our keyboard and screen connected to the program's standard
input and output, though, the shell hangs onto them. This means the
shell can give us a fresh command prompt, and start running other
commands, right away. Here, for example, we're putting some parameters
for the next run of the program in a file:

~~~{.input}
$ cat > params.txt
~~~
~~~{.output}
density: 22.0
viscosity: 0.75
^D
~~~

(Remember, \^D is the shell's way of showing Control-D, which means "end
of input".) Now let's run the `jobs` command, which tells us what
processes are currently running in the background:

~~~{.input}
$ jobs
~~~
~~~{.output}
[1] ./analyze results01.dat results02.dat results03.dat
~~~

Since we're about to go and get coffee, we might as well use the
foreground command, `fg`, to bring our background job into the
foreground:

~~~{.input}
$ fg
~~~
~~~
...a few minutes pass...
~~~

When `analyze` finishes running, the shell gives us a fresh prompt as
usual. If we had several jobs running in the background, we could
control which one we brought to the foreground using `fg %1`, `fg %2`,
and so on. The IDs are *not* the process IDs. Instead, they are the job
IDs displayed by the `jobs` command.

The shell gives us one more tool for job control: if a process is
already running in the foreground, Control-Z will pause it and return
control to the shell. We can then use `fg` to resume it in the
foreground, or `bg` to resume it as a background job. For example, let's
run `analyze` again, and then type Control-Z. The shell immediately
tells us that our program has been stopped, and gives us its job number:

~~~{.input}
$ ./analyze results01.dat

^Z
~~~
~~~{.output}
[1] Stopped ./analyze results01.dat
~~~

If we type `bg %1`, the shell starts the process running again, but in
the background. We can check that it's running using `jobs`, and kill it
while it's still in the background using `kill` and the job number. This
has the same effect as bringing it to the foreground and then typing
Control-C:

~~~{.input}
$ bg %1
$ jobs
~~~
~~~{.output}
[1] ./analyze results01.dat
~~~
~~~{.input}
$ kill %1
~~~

Job control was important when users only had one terminal window at a
time. It's less important now: if we want to run another program, it's
easy enough to open another window and run it there. However, these
ideas and tools are making a comeback, as they're often the easiest way
to run and control programs on remote computers elsewhere on the
network.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "easiest way" is rather hand wavy. These tools help if you only want to have one SSH terminal session open, is that what is meant here?