ObjectiveLearn the fundamentals of processes management on Linux
Operating System and Software Versions
- Operating System: - All Linux distributions
- Some programs mentioned in this tutorial require root access
- # - requires given linux commands to be executed with root privileges either directly as a root user or by use of
- $ - requires given linux commands to be executed as a regular non-privileged user
IntroductionOne of the core activities of a system administrator is that of monitoring and interacting with the processes running on a machine. In this tutorial you will be introduced to the use of some fundamental tools that will help you accomplish that vital task.
The ps commandPs is one of the fundamental programs used in process monitoring: it basically gives you a
snapshotof the processes running on a machine at the moment you invoke the command. Let's see it in action: first we will try to run it without any options:
$ ps PID TTY TIME CMD 24424 pts/0 00:00:00 bash 24468 pts/0 00:00:00 psAs you can see from the output above, only two processes are shown:
psitself with the pid
24468. This is because when invoked without any option, the
pscommand shows processes associated with the
UIDof the user who launched the command, and the terminal from which it is invoked.
How to overcome this limitation? Using the
-aoption we can make
psto show us all processes, with the exception of the
session leadersand the processes not associated with a terminal.
A session leader is a process which has a PID that is the same of the
SID(Session Id) of the session of which it is (the first) member. When a process is created it is made part of the same session of its parent process: since by convention the session id is the same of the
PIDof its first member, we call this process a
session leader. Let's try to run
-aoption and check its output:
$ ps -a PID TTY TIME CMD 12466 tty1 00:00:00 gnome-session-b 12480 tty1 00:00:17 gnome-shell 12879 tty1 00:00:00 Xwayland 12954 tty1 00:00:00 gsd-sound 12955 tty1 00:00:00 gsd-wacom 12957 tty1 00:00:00 gsd-xsettings 12961 tty1 00:00:00 gsd-a11y-keyboa 12962 tty1 00:00:00 gsd-a11y-settin 12965 tty1 00:00:00 gsd-clipboard 12966 tty1 00:00:03 gsd-color 12967 tty1 00:00:00 gsd-datetime 12970 tty1 00:00:00 gsd-housekeepin 12971 tty1 00:00:00 gsd-keyboard 12972 tty1 00:00:00 gsd-media-keys 12973 tty1 00:00:00 gsd-mouse 12976 tty1 00:00:00 gsd-orientation [...]The output of the program has been truncated, but you can easily see that it now includes processes which belong to different terminals and users. The output shows us information about
PIDin the first column,
TTYin the second,
TIMEwhich is the cumulative time the CPU spent on the process, and
CMDwhich is the command that started the process.
To have an even richer output we can add the
-xoptions: the former tells
psto do a selection by
user id, while the latter instructs the program to include also processes not associated with a terminal, such as daemons:
$ ps -aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.2 223932 8708 ? Ss Jul20 0:04 /usr/lib/systemd/systemd --switched-root --system --deserialize 25 root 2 0.0 0.0 0 0 ? S Jul20 0:00 [kthreadd] root 4 0.0 0.0 0 0 ? S< Jul20 0:00 [kworker/0:0H] root 6 0.0 0.0 0 0 ? S< Jul20 0:00 [mm_percpu_wq] root 7 0.0 0.0 0 0 ? S Jul20 0:00 [ksoftirqd/0] root 8 0.0 0.0 0 0 ? S Jul20 0:07 [rcu_sched] root 9 0.0 0.0 0 0 ? S Jul20 0:00 [rcu_bh] root 10 0.0 0.0 0 0 ? S Jul20 0:04 [rcuos/0] root 11 0.0 0.0 0 0 ? S Jul20 0:00 [rcuob/0] root 12 0.0 0.0 0 0 ? S Jul20 0:00 [migration/0] root 13 0.0 0.0 0 0 ? S Jul20 0:00 [watchdog/0] root 14 0.0 0.0 0 0 ? S Jul20 0:00 [cpuhp/0] root 15 0.0 0.0 0 0 ? S Jul20 0:00 [cpuhp/1] root 16 0.0 0.0 0 0 ? S Jul20 0:00 [watchdog/1] root 17 0.0 0.0 0 0 ? S Jul20 0:00 [migration/1] root 18 0.0 0.0 0 0 ? S Jul20 0:00 [ksoftirqd/1] root 20 0.0 0.0 0 0 ? S< Jul20 0:00 [kworker/1:0H] root 21 0.0 0.0 0 0 ? S Jul20 0:02 [rcuos/1] root 22 0.0 0.0 0 0 ? S Jul20 0:00 [rcuob/1] root 23 0.0 0.0 0 0 ? S Jul20 0:00 [cpuhp/2] root 24 0.0 0.0 0 0 ? S Jul20 0:00 [watchdog/2] root 25 0.0 0.0 0 0 ? S Jul20 0:00 [migration/2] root 26 0.0 0.0 0 0 ? S Jul20 0:00 [ksoftirqd/2] root 28 0.0 0.0 0 0 ? S< Jul20 0:00 [kworker/2:0H] [...] egdoc 13128 0.0 0.1 74736 5388 ? Ss Jul20 0:00 /usr/lib/systemd/systemd --user egdoc 13133 0.0 0.0 106184 420 ? S Jul20 0:00 (sd-pam) egdoc 13143 0.0 0.1 218328 3612 ? Sl Jul20 0:00 /usr/bin/gnome-keyring-daemon --daemonize --login [...]You can see that quite a lot of new information has been added. The first new column of the output is
%CPU: this shows the cpu utilization of the process, expressed as a percentage. A percentage is also used for the next column,
%MEM, which shows the physical memory on the machine used by the process.
VSZis the virtual memory size of the process expressed in KiB.
STATcolumn uses a code to express the process state. We are not going to describe all possible states here, but just explain the ones appearing in the output above (you can have a complete overview by consulting the ps manpage).
Let's examine the first process in the output: it is has
PID 1, therefore is the first process launched by the kernel. This makes sense, we can see that it is
systemd, the relatively new Linux init system, now adopted by almost all distributions. First of all we have an
Swhich indicates that the process is in the state of
interruptible sleepwhich means that it is idle, and will wake up as soon as it receives an input. The
s, instead, tells us that the process is a
Another symbol, not appearing in the first raw, but in some of the other processes descriptions is
<which indicates that the process has high priority, and therefore a low
nicevalue (we will see what a nice value is in the relevant section of this tutorial). An
STATcolumn, indicates that the process is multi-threaded, and a
+sign, that it is in the foreground process group.
Finally, in the last column, we have the
STARTcolumn, showing the time the command started.
Another nice option we can pass to the
-o, which is the short version of
--format. This option let's you modify the output by the use of placeholders, specifying what columns to show. For example, running:
$ ps -ax -o %U%p%n%cWill give us the
USERcolumn first (%U), followed by the
PIDof the process (%p), by the
NIcolumn (%n), which indicates the
nicelevel, and finally by the
USER PID NI COMMAND root 1 0 systemd root 2 0 kthreadd root 4 -20 kworker/0:0H root 6 -20 mm_percpu_wq root 7 0 ksoftirqd/0 root 8 0 rcu_sched root 9 0 rcu_bh root 10 0 rcuos/0 root 11 0 rcuob/0 root 12 - migration/0 root 13 - watchdog/0 root 14 0 cpuhp/0 root 15 0 cpuhp/1 root 16 - watchdog/1 root 17 - migration/1 root 18 0 ksoftirqd/1 root 20 -20 kworker/1:0H root 21 0 rcuos/1 root 22 0 rcuob/1 root 23 0 cpuhp/2 root 24 - watchdog/2 root 25 - migration/2 root 26 0 ksoftirqd/2
Using 'top' to dynamically interact with processesWhile
psgives us a static snapshot of processes and their information at the time you run it,
topgives us a dynamic view of the processes, updated at a specified time interval that we can specify both when launching the program and interactively (default is 3 seconds).
Top doesn't just show us a dynamic representation of the running processes: we can interact with them and with the program itself, by the use of some keys. For example, pressing
Blets us toggle the use of bold characters,
dlets us enter a value to change the delay time,
klets us send a signal to a process by prompting for its
PIDand for the
SIGTERMbeing the default.
Change priority of processes with nice and reniceAs we have seen before, each process have a
priorityassigned to it, which indicates how much the process have to wait for other processes to free resources before it can access them. This priority can be specified with a value which is in a range that goes from
19. The less the value, the highest the priority of the process. This can seem counter-intuitive at first, but see it this way: the nicer the process is to other processes, the more they will surpass it in accessing the resources.
But how can we set the priority of a process? We can use the
niceprogram to accomplish the task. Say you want to run a script with the lowest possible priority value: you would preface it this way:
$ nice -n 19 ./script.shYou can also change the priority of a program that is already running by the use of
# renice -n 15 PIDWhere PID is the process id of the program. Just remember that the
renicecommand must be run with root permissions.
Send signals to processes with the kill and killall commandsWe can use the kill command to send a
signalto a process which belong to us, or to every process if we have root permissions. The various signals we can send are identified by a number: we can easily see these correspondences by running the kill command with the
$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAXIf no option is passed to the
killcommand, by default it will send a
SIGTERMsignal to the specified process, to which the latter could react in various ways: it may stop immediately, try to do some cleanup before stopping, or just ignore the signal.
To specify the signal to be sent using kill, we run the command followed by a dash and the number of the signal to be sent. For example to run a
SIGKILLsignal we should run:
kill -9 PIDThe
SIGTERMcannot be caught by the process, which cannot react: it will just be terminated immediately.
Another signal you will often see is
SIGINTwhich is the signal that is sent on keyboard interrupt (CTRL-c). It also tries to terminate the process in a graceful way, and can be ignored by the process.
SIGCONTwill respectively suspend and resume the execution of a process: the former, like
SIGKILLcannot be caught or ignored. For a complete list and description of signals you can consult the manual for
man 7 signalThe
killallprogram has the same purpose of
kill, and like kill, sends a
SIGTERMsignal when no other is specified, (this time with the
--signaloption), but instead of referencing a process by its
PID, it will do it by command name, effectively killing all processes running under the same one.