There are many Unix commands, and most have several different arguments and options, making it implausible to remember all but a small number of them. Unix systems come with a built in manual, called "man pages".
To look up the man page for a specific command, use the
and pass the command to lookup as the argument. For example, to read the man
cp, we could run the following command:
finlaysoni@myvm:~$ man cp
You would then see the manual:
The man page for cp.
man pages contain a synopsis section which gives you the basic syntax
of the command. There may be several lines in the synopsis section which each
give a different usage. In the
cp example, there are three:
cp [OPTION]... [-T] SOURCE DEST cp [OPTION]... SOURCE... DIRECTORY cp [OPTION]... -t DIRECTORY SOURCE...
In the synopsis lines, anything inside of brackets, like [OPTION], is optional. The "..." means that there can be multiple of the preceding element. For example, the first line allows only one source, but the second allows multiple.
The first line is the case where one file is being copied to another location. The second is when multiple sources are copied. In this instance, the final parameter must be a directory - not another file. The third shows us a way of specifying the destination directory before the sources with the -t option, if we ever needed to do that for some reason.
The description section of the man page for
cp lists all of the
options that the command accepts with a description of each one.
Most commands accept two types of options, short and long. For example,
cp has this option in its man page:
-v, --verbose explain what is being done
cp -v and
cp --verbose are exactly identical.
The short options are probably more common and that is what I will mostly use
in this course.
Some options do not have a short form, however, such as the
Some options also require values to be set for them.
One example is the "-t" flag to
cp which is describes thusly in the man page:
-t, --target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY
When using the short version of this option, the required value (DIRECTORY in this case) comes right after the option. So to use this option to copy some files to the /tmp/ directory we could use:
finlaysoni@myvm:~$ cp -t /tmp/ file1 file2
With the long form of an option however, an equal sign character is placed between the option and the required value. To run the above command using the long form option would look like this:
finlaysoni@myvm:~$ cp --target-directory=/tmp/ file1 file2
The man program, like Vim, suspends your normal shell until you exit out of it. man supports a few commands which allow you to navigate the manual:
|Space||Scroll down one window.|
|g||Go to the top.|
|G||Go to the end.|
|h||Display a help screen.|
As you can see, the short cuts are modeled after those of Vim.
Like Vim, when you search with / or ?, you enter your search term right after typing the / or ? character, then hit enter to search for it. Also like Vim, you move to the next match with the 'n' key and to the previous match with the 'N' key.
A process is an instance of a program that is currently running. Using the command line, nearly every command that you type launches a new process which runs until it finishes. When you run your own programs, those will run as processes as well.
Usually processes start, do their work, and finish without our having to worry about it, but sometimes we will want or need to intervene.
We can list the processes which are running on a system with the
command. With no options,
ps will list the only the processes which
we have started in the current terminal ourselves:
finlaysoni@myvm:~$ ps PID TTY TIME CMD 17371 pts/0 00:00:00 bash 17386 pts/0 00:00:00 ps
There is a line for each of the two processes which I have launched. The
first is "bash" which is the shell process. That is the program which is
interpreting my key presses as commands. The second is the
itself. Because it is running at the time when it lists processes, it includes
itself in the output.
The output includes the following columns by default:
The unique process identifier. This can be used to manage individual processes as we will see.
TTY stands for "TeleTYpewriter", an old term for a computer terminal which could send commands to a mainframe computer. Here, TTY refers to which terminal the process was launched under. The 'p' in "pts/0" stands for "pseudo" which indicates the terminal is a virtual one managed for us by the SSH server. You normally don't need to worry about the TTY, but if you have multiple SSH windows connected at once, the TTY indicates which one a process belongs to.
The amount of CPU time that the process has used. Neither
ps are CPU intensive, so they have used less than one second each.
The command which was used to initially launch the process.
ps just shows processes from our current session and
user. We can also view all processes running on a system by passing
ps the "-A" flag. Here is a small subset of the output when I ran it
(the full list had 96 processes):
finlaysoni@myvm:~$ ps -A PID TTY TIME CMD 1 ? 00:00:01 systemd 2 ? 00:00:00 kthreadd 4 ? 00:00:00 kworker/0:0H 12030 ? 00:00:00 apache2 12194 ? 00:00:00 apache2 12203 ? 00:00:00 apache2 6586 pts/0 00:00:00 bash 6624 ? 00:00:00 sshd 6705 ? 00:00:00 sshd 6706 pts/1 00:00:00 bash 6711 pts/1 00:00:00 man 6893 pts/0 00:00:00 ps
The first process, with a PID of 1 is the "systemd" process which runs when the operating system first boots and is responsible for getting everything else going.
A few other processes you will see are "apache2" which is the web server running on my VM. The "sshd" process is the SSH server. There are multiple of these server processes because they create a new process to handle each client connection.
I also have two terminals connected, one running man, and one running ps. This is why there is a pts/0 and pts/1.
Normally, when we launch a process via the command line, it runs to
completion and we cannot interact with the shell until it finishes. For
instance, try running the
sleep command which does nothing but
runs for the number of seconds given as its argument:
finlaysoni@myvm:~$ sleep 3 finlaysoni@myvm:~$
This command produces no output, but runs for three seconds. Try running
this command and you will see that commands we enter take control of the shell
because, during the three seconds during which
sleep is executing, we
are not able to use the command prompt. This is true for all of the other
commands we have discussed, but they generally run so quickly that we cannot
To run a command in the background, we can end it with the & character. This launches the process, except it returns control back to the shell immediately. In the following example, we run the sleep command in the background, and are able to execute commands immediately after:
finlaysoni@myvm:~$ sleep 3 &  3149 finlaysoni@myvm:~$ ps PID TTY TIME CMD 2982 pts/3 00:00:00 bash 3149 pts/3 00:00:00 sleep 3150 pts/3 00:00:00 ps finlaysoni@myvm:~$  + done sleep 3 finlaysoni@myvm:~$ ps PID TTY TIME CMD 2982 pts/3 00:00:00 bash 3151 pts/3 00:00:00 ps finlaysoni@myvm:~$
sleep in the background, I immediately ran the
command which shows that sleep is currently running. After the three seconds have
elapsed, the shell gives the message " + done sleep 3" informing me that
sleep has finished executing. Also notice that the shell gives us the
process ID for the sleep command as it launches it.
Running the sleep command in the background is not terribly useful, but starting long-running commands in the background (such as copy commands of large amounts of data) is useful. It's also useful when writing our own server-style programs, where the program runs in the background and we interact with it some other way.
To cancel a process that is currently running (not in the background), you can use the Control-C shortcut. For example, we can cancel a sleep command:
finlaysoni@myvm:~$ sleep 100 ^C finlaysoni@myvm:~$ ps PID TTY TIME CMD 17453 pts/3 00:00:00 bash 17471 pts/3 00:00:00 ps
As you can see, this ends the process. This is helpful when writing our own programs. If we have an infinite loop, killing the program is the only way to stop it!
We can also suspend a process that is running with the Control-Z shortcut. This does not kill the process, but pauses it, returning control to your shell:
finlaysoni@myvm:~$ sleep 100 ^Z + Stopped sleep 100 finlaysoni@myvm:~$ ps PID TTY TIME CMD 17680 pts/3 00:00:00 bash 17683 pts/3 00:00:00 sleep 17686 pts/3 00:00:00 ps
As you can see, in this case, the
sleep command is still in the process list
However, as a suspended process it does not actually continue to execute, it is "paused".
We can see a list of all suspended processes with the
finlaysoni@myvm:~$ jobs  + suspended sleep 100
To resume the process that was most recently suspended, use the
The process I most often suspend is Vim. For example, I might suspend Vim, check a man
page and then resume Vim using fg. This might look like this:
finlaysoni@myvm:~$ vim program.c bash: suspended vim program.c finlaysoni@myvm:~$ man fg finlaysoni@myvm:~$ fg
Here I used Control-Z to suspend Vim, ran some other command(s), and then went back to Vim with the fg command.
If there are multiple suspended commands, you can select the one you wish to
resume by passing the number assigned to it in the output of
jobs with a
finlaysoni@myvm:~$ jobs  suspended vim a.txt  - suspended vim b.txt  + suspended vim c.txt
Here, there are three Vim processes which have all been suspended. To resume the first one we would use:
finlaysoni@myvm:~$ fg %1
Likewise, passing "%2" or "%3" would resume the second and third processes
listed in the output of
We can also resume a process with the
bg command. The difference
bg is that
fg resumes the command in
the foreground - as if the process was launched normally - while
resumes the process but in the background - as if the process was launched with
an & at the end.
Resuming a process like Vim in the background makes little sense, but we can
use Control-Z and
bg to send a process to the background after it was
initially launched in the foreground, which can be useful. For instance,
sometimes I will run a program, and realize that it is taking a long time.
Instead of waiting, we can suspend it, then run it in the background with
bg, and then carry on with other tasks instead of waiting
We can also interact with running processes by sending them signals. A signal is a message that is passed to a running process, telling it to do something. When we cancel a process with Control-C, we are actually sending it the "SIGINT" signal (which stands for "signal interrupt"). Likewise, hitting Control-Z sends the process the "SIGTSTP" (which stands for "signal stop").
We can send these, and other, signals to a process with the
It is named "kill" because the default behavior of
kill is to send
the "SIGTERM" signal which terminates a process.
kill takes the process
id of the process to which it will send a signal.
The example below shows how
kill can be used to terminate a process which
is running in the background:
finlaysoni@myvm:~$ sleep 100 &  18167 finlaysoni@myvm:~$ ps PID TTY TIME CMD 17792 pts/1 00:00:00 bash 18167 pts/1 00:00:00 sleep 18168 pts/1 00:00:00 ps finlaysoni@myvm:~$ kill 18167  + terminated sleep 100 finlaysoni@myvm:~$ ps PID TTY TIME CMD 17792 pts/1 00:00:00 bash 18175 pts/1 00:00:00 ps
The process id (18167 in this case) can be seen in the output of
Sometimes processes do not respond to the SIGTERM signal. Processes are able to catch it and handle it in a graceful way if they can. In some cases, processes do not terminate even when given the signal to. In these cases, we can use the more extreme "SIGKILL" signal which kills processes without giving them a chance to respond.
This is done by passing the "-KILL" option, or as is more common, by passing the "-9" option:
finlaysoni@myvm:~$ sleep 100 &  18196 finlaysoni@myvm:~$ ps PID TTY TIME CMD 17792 pts/1 00:00:00 bash 18196 pts/1 00:00:00 sleep 18197 pts/1 00:00:00 ps finlaysoni@myvm:~$ kill -9 18196 finlaysoni@myvm:~$  + killed sleep 100
kill which sends SIGTERM and
kill -9 which sends SIGKILL
are by far the most commonly sent signals, but there are other signals which
kill is able to send. For example, "SIGUSR1" is ignored by most
commands, but a few use it for some special purpose. For example,
(a command for copying files and disk drives), prints its progress when sent
the USR1 signal. You can see
man kill for a complete list.
killall command can also send signals to processes.
works very similarly to
kill except that instead of passing the process id as
an argument, we pass the name of the command to send the signal to.
will send the signal to all processes with that name.
For example, the following shows how we could send the SIGTERM signal to all sleep processes:
finlaysoni@myvm:~$ sleep 100 &  1482 finlaysoni@myvm:~$ sleep 101 &  1483 finlaysoni@myvm:~$ sleep 102 &  1484 finlaysoni@myvm:~$ ps PID TTY TIME CMD 1472 pts/2 00:00:00 bash 1482 pts/2 00:00:00 sleep 1483 pts/2 00:00:00 sleep 1484 pts/2 00:00:00 sleep 1485 pts/2 00:00:00 ps finlaysoni@myvm:~$ killall sleep  terminated sleep 100  - terminated sleep 101  + terminated sleep 102 finlaysoni@myvm:~$ ps PID TTY TIME CMD 1472 pts/2 00:00:00 bash 1488 pts/2 00:00:00 ps
htop command can be used to view dynamic process activity. It
displays which processes are currently using the CPU and memory of the machine.
htop updates the display every second until you exit the program by
pressing the 'q' key. Below is a screen shot of htop:
The output of htop.
Here, I am running a CPU-intensive program called "knapsack" which is using 2 processes taking 100% CPU each. You can also see htop itself, and some system processes running.
htop is helpful for finding which processes are taking up system
resources. The process ids are also listed in the first column.
You can use the arrow keys to scroll through the processes. As you can see
on the bottom of the screen, you can use F9 to Kill a process. That brings up
a menu asking you which signal you wish to send to the chosen process.
htop is a convenient way to find and kill rogue processes.
Copyright © 2022 Ian Finlayson | Licensed under a Creative Commons Attribution 4.0 International License.