Zu Befehl Auch wenn sich viele Dinge bequem über grafische Oberflächen wie KDE oder GNOME regeln lassen – wer sein Linux-System richtig ausreizen möchte, kommt um die Kommandozeile nicht herum. Abgesehen davon gibt es auch sonst viele Situationen, in denen es gut ist, sich im Befehlszeilendschungel ein wenig auszukennen. In der letzten „Zu Befehl“-Folge ging es um screen und viele virtuelle Konsolen in nur einem Terminal-Fenster – da spielt es keine Rolle, wie viele Prozesse laufen und ob diese gerade das Terminal „belegen“. Ist aber kein screen vorhanden und die Anzahl der Konsolen endlich, hilft es zu wissen, wie man Programme direkt im Hintergrund startet, unterbricht und nachträglich in den Hintergrund oder wieder nach vorne bringt. Wir zeigen, wie Sie die Kontrolle über alle Jobs behalten. Ab in den Hintergrund Läuft ein auf der Konsole gestarteter Befehl einmal etwas länger, ist oft Daumendrehen angesagt – das Terminal ist nämlich für die Dauer der Programmausführung belegt, so dass Sie keine weiteren Befehle eingeben können. Da ist es praktisch, dass Sie den Prozess gleich beim Start in den Hintergrund schieben können. Dazu hängen Sie an den Befehl ein kaufmännisches „Und“ (&) an, z. B.: $ find . -name bla > /tmp/liste & [1] 664 Außer dem Eingabe-Prompt, der direkt wieder freigegeben wird, sehen Sie in der Ausgabe ein paar Informationen über den gestarteten Prozess: In den eckigen Klammern steht die Job-ID, dahinter die Prozess-ID (PID, Process IDentifier). Während letztere im ganzen System eindeutig ist [1], ist die Job-ID eine von der Shell vergebene fortlaufende Job-Nummer. Das Kommando jobs verrät Ihnen, welche Jobs derzeit in dieser Shell laufen: $ jobs [1]+ Stopped find . -name bla >/tmp/liste Einen Prozess, der ohne das kaufmännische Und in der Shell gestartet wurde, der also im Vordergrund seine Arbeit verrichtet, können Sie auch nachträglich mit wenigen Kommandos in den Hintergrund schicken. Dazu unterbrechen Sie zunächst den Prozess, z. B. über die Tastenkombination [Strg-Z]. Die anschließende Ausgabe verrät wiederum die Job-ID und den Namen des angehaltenen Befehls. Danach erscheint wieder der Eingabe-Prompt. Um den angehaltenen Prozess in den Hintergrund zu befördern und dort fortzusetzen, verwenden Sie das Kommando bg (für englisch „background“): $ bg [1]+ find . -name bla >/tmp/liste & Sie sehen in dieser Ausgabe nicht nur die Job-ID, sondern auch den Namen des vollständigen Befehls und zum Schluss wieder das kaufmännische Und, das anzeigt, dass der Prozess jetzt im Hintergrund läuft. Sollte mehr als ein Job in der Shell laufen und angehalten worden sein, braucht das Kommando bg noch die Information, welchen Prozess Sie im Hintergrund fortsetzen wollen. Standardmäßig legt bg den Prozess mit der höchsten Job-Nummer in den Hintergrund. Dazu können Sie zunächst wieder mit dem Befehl jobs nachschauen, welche Job-IDs es gibt. Anschließend setzen Sie für das bg-Kommando die Job-ID hinter ein Prozentzeichen: $ jobs [1]- Stopped find . -name blubb >/tmp/liste [2]+ Stopped find . -name bla >/tmp/liste $ bg %2 [2]+ find . -name bla >/tmp/liste & Vordergründig Um einen Hintergrund-Job zurück in den Vordergrund zu befördern, setzen Sie das Kommando fg (englisch: „foreground“) ein. Auch dieser Befehl benötigt im Zweifelsfall die Angabe, um welchen Job es sich handelt, also z. B.: fg %2 Die Shell ist anschließend wieder solange „blockiert“, wie der Prozess im Vordergrund läuft bzw. abgearbeitet wird. Wenn ein Prozess mit seiner Arbeit fertig ist, informiert er Sie übrigens am Shell-Prompt darüber: $ [3]- Done sleep 5 Abgekürzt Die Bash überrascht auch erfahrene Benutzer immer wieder mit netten Abkürzungen und Variablen, die dem Administrator das Leben leichter machen. So steht das Ausrufezeichen als Variable beispielsweise für die Prozess-ID des zuletzt gestarteten Hintergrundprozesses. Die folgenden Befehle zeigen zunächst zusätzlich zur Job-ID die Prozess-ID an (jobs -l) und gibt anschließend mit dem Kommando echo die Prozess-ID des zuletzt gestarteten Hintergrundprozesses ($!) an: $ sleep 100 & $ jobs -l [1]+ 1057 Stopped sleep 1000 [2] 1058 Running sleep 1000 & [3]- 1066 Running sleep 100 & $ echo $! 1066 Diese Information können Sie nun ganz geschickt einsetzen, um den letzten Prozess anzuhalten. Dazu kommt allerdings nicht das Kommando fg (dieses benötigt ja die Job-ID) mit anschließendem [Strg-Z] zum Einsatz, sondern ganz einfach das kill-Kommando: Es schießt Prozesse nicht nur einfach ab, sondern sendet ihnen auch alle möglichen Signale [1]. Eine Übersicht erhalten Sie, indem Sie kill -l tippen (oder wahlweise die Man-Page man 7 signal lesen). In diesem Fall setzen Sie das Signal -STOP ein: $ kill -STOP $! $ jobs -l [1]- 1057 Stopped sleep 1000 [2] 1058 Running sleep 1000 & [3]+ 1066 Stopped (signal) sleep 100 & Kontaktscheu Eine Möglichkeit, Prozesse nach Beenden der Shell weiterlaufen zu lassen, bietet das Kommando nohup. Zum Abkoppeln setzen Sie nohup vor den eigentlichen Befehl und hängen das kaufmännische Und an, um den Prozess in den Hintergrund zu legen. Die Ausgabe verrät: $ nohup sleep 1000 & [1] 1116 nohup: appending output to `nohup.out' Auf diese Weise läuft der Prozess auch dann weiter, wenn Sie die Shell durch Eingabe von exit oder [Strg-D] verlassen. In der Datei nohup.out können Sie anschließend nachlesen, was in Ihrer Abwesenheit passiert ist. Kontrollierte Jobs Mit dem Befehl nice weisen Sie Prozessen eine bestimmte Priorität zu – das ist praktisch, wenn ein Programm im Hintergrund werkelt und Sie nicht die Kontrolle über die Auslastung des Systems verlieren wollen. Als einfacher Benutzer dürfen Sie die Priorität allerdings nur herabsetzen, und das auch nur für von Ihnen gestartete Prozesse – lediglich der Administrator darf die Priorität erhöhen. Standardmäßig erhalten Prozesse den nice-Wert 0; geben Sie stattdessen -20 als Wert mit auf den Weg, bedeutet das höchste Priorität, 19 die niedrigste. Der Parameter wird direkt an den Aufruf angehängt: nice -10 find . -name bla >/tmp/liste Schauen Sie sich anschließend mit dem ps-Kommando den Status des Prozesses an, sehen Sie, dass dieser find-Aufruf „genicet“ wurde: $ ps auxwww […] huhn 1200 0.2 0.6 1520 404 pts/7 RN+ 23:02 0:00 find . -name bla […] Eine bessere Möglichkeit, den nice-Level von Programmen herauszufinden, bietet der Befehl top. Dieses Programm listet Prozesse, sortiert nach ihrem Anteil an CPU-Zeit, auf. In der vierten Spalte unter NI steht jeweils der nice-Level (Abbildung 1). Abbildung-1 Abbildung 1: Das Kommando „top“ zeigt auch den „nice“-Level an. A cool trick $ps -ejH You will get all the processes with names Job Specification The jobs command as well as other utilities such as fg, bg and kill (that you will see in the next section) need a job specification (or jobspec) to act upon a particular job. As we have just seen, this can be — and normally is — the job ID preceded by %. However, other job specifications are also possible. Let us have a look at them: %n Job whose id number is n: $ jobs %1 [1]+ Stopped sleep 60 %str Job whose command line starts with str: $ jobs %sl [1]+ Stopped sleep 60 %?str Job whose command line contains str: $ jobs %?le [1]+ Stopped sleep 60 %+ or %% Current job (the one that was last started in the background or suspended from the foreground): $ jobs %+ [1]+ Stopped sleep 60 %- Previous job (the one that was %+ before the default, current one): $ jobs %- [1]+ Stopped sleep 60 In our case, since there is only one job, it is both current and previous. Job Status: Suspension, Foreground and Background Once a job is in the background or has been suspended, we can do any of three things to it: Take it to the foreground with fg: $ fg %1 sleep 60 fg moves the specified job to the foreground and makes it the current job. Now we can wait until it finishes, stop it again with Ctrl+Z or terminate it with Ctrl+C. Take it to the background with bg: $ bg %1 [1]+ sleep 60 & Once in the background, the job can be brought back into the foreground with fg or killed (see below). Note the ampersand (&) meaning the job has been sent to the background. As a matter of fact, you can also use the ampersand to start a process directly in the background: $ sleep 100 & [2] 970 Together with the job ID of the new job ([2]), we now get its process ID (970) too. Now both jobs are running in the background: $ jobs [1]- Running sleep 60 & [2]+ Running sleep 100 & A bit later the first job finishes execution: $ jobs [1]- Done sleep 60 [2]+ Running sleep 100 & Terminate it through a SIGTERM signal with kill: $ kill %2 To make sure the job has been terminated, run jobs again: $ jobs [2]+ Terminated sleep 100 Note If no job is specified, fg and bg will act upon the current, default one. kill, however, always needs a job specification. Detached Jobs: nohup The jobs we have seen in the previous sections were all attached to the session of the user who invoked them. That means that if the session is terminated, the jobs are gone. However, it is possible to detach jobs from sessions and have them run even after the session is closed. This is achieved with the nohup (“no hangup”) command. The syntax is as follows: nohup COMMAND & Remember, the & sends the process into the background and frees up the terminal you are working at. Let us detach the background job ping localhost from the current session: $ nohup ping localhost & [1] 1251 $ nohup: ignoring input and appending output to 'nohup.out' ^C The output shows us the job ID ([1]) and the PID (1251), followed by a message telling us about the file nohup.out. This is the default file where stdout and stderr will be saved. Now we can press Ctrl+C to free up the command prompt, close the session, start another one as root and use tail -f to check if the command is running and output is being written to the default file: $ exit logout $ tail -f /home/carol/nohup.out 64 bytes from localhost (::1): icmp_seq=3 ttl=64 time=0.070 ms 64 bytes from localhost (::1): icmp_seq=4 ttl=64 time=0.068 ms 64 bytes from localhost (::1): icmp_seq=5 ttl=64 time=0.070 ms ^C Tip Instead of using the default nohup.out you could have specified the output file of your choice with nohup ping localhost > /path/to/your/file &. If we want to kill the process, we should specify its PID: # kill 1251 Process Monitoring A process or task is an instance of a running program. Thus, you create new processes every time you type in commands into the terminal. The watch command executes a program periodically (2 seconds by default) and allows us to watch the program’s output change over time. For instance, we can monitor how the load average changes as more processes are run by typing watch uptime: Every 2.0s: uptime debian: Tue Aug 20 23:31:27 2019 23:31:27 up 21 min, 1 user, load average: 0.00, 0.00, 0.00 The command runs until interrupted so we would have to stop it with Ctrl+C. We get two lines as output: the first one corresponds to watch and tells us how often the command will be run (Every 2.0s: uptime), what command/program to watch (uptime) as well as the hostname and date (debian: Tue Aug 20 23:31:27 2019). The second line of output is uptime’s and includes the time (23:31:27), how much time the system has been up (up 21 min), the number of active users (1 user) and the average system load or number of processes in execution or in waiting state for the last 1, 5 and 15 minutes (load average: 0.00, 0.00, 0.00). Similarly, you can check on memory use as new processes are created with watch free: Every 2.0s: free debian: Tue Aug 20 23:43:37 2019 23:43:37 up 24 min, 1 user, load average: 0.00, 0.00, 0.00 total used free shared buff/cache available Mem: 16274868 493984 14729396 35064 1051488 15462040 Swap: 16777212 0 16777212 To change the update interval for watch use the -n or --interval options plus the number of seconds as in: $ watch -n 5 free Now the free command will run every 5 seconds. For more information about the options for uptime, free and watch, please refer to their manual pages. Note The information provided by uptime and free is also integrated in the more comprehensive tools top and ps (see below). Sending Signals to Processes: kill Every single process has a unique process identifier or PID. One way of finding out the PID of a process is by using the pgrep command followed by the process' name: $ pgrep sleep 1201 Note A process' identifier can also be discovered through the pidof command (e.g. pidof sleep). Similar to pgrep, pkill command kills a process based on its name: $ pkill sleep [1]+ Terminated sleep 60 To kill multiple instances of the same process, the killall command can be used: $ sleep 60 & [1] 1246 $ sleep 70 & [2] 1247 $ killall sleep [1]- Terminated sleep 60 [2]+ Terminated sleep 70 Both pkill and killall work much in the same way as kill in that they send a terminating signal to the specified process(es). If no signal is provided, the default of SIGTERM is sent. However, kill only takes either a job or a process ID as an argument. Signals can be specified either by: Name: $ kill -SIGHUP 1247 Number: $ kill -1 1247 Option: $ kill -s SIGHUP 1247 To have kill work in a similar way to pkill or killall (and save ourselves the commands to find out PIDs first) we can use command substitution: $ kill -1 $(pgrep sleep) As you should already know, an alternative syntax is kill -1 `pgrep sleep`. Tip For an exhaustive list of all kill signals and their codes, type kill -l into the terminal. Use -KILL (-9 or -s KILL) to kill rebel processes when any other signal fails. top and ps When it comes to process monitoring, two invaluable tools are top and ps. Whilst the former produces output dynamically, the latter does it statically. In any case, both are excellent utilities to have a comprehensive view of all processes in the system. Interacting with top To invoke top, simply type top: $ top top - 11:10:29 up 2:21, 1 user, load average: 0,11, 0,20, 0,14 Tasks: 73 total, 1 running, 72 sleeping, 0 stopped, 0 zombie %Cpu(s): 0,0 us, 0,3 sy, 0,0 ni, 99,7 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st KiB Mem : 1020332 total, 909492 free, 38796 used, 72044 buff/cache KiB Swap: 1046524 total, 1046524 free, 0 used. 873264 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 436 carol 20 0 42696 3624 3060 R 0,7 0,4 0:00.30 top 4 root 20 0 0 0 0 S 0,3 0,0 0:00.12 kworker/0:0 399 root 20 0 95204 6748 5780 S 0,3 0,7 0:00.22 sshd 1 root 20 0 56872 6596 5208 S 0,0 0,6 0:01.29 systemd 2 root 20 0 0 0 0 S 0,0 0,0 0:00.00 kthreadd 3 root 20 0 0 0 0 S 0,0 0,0 0:00.02 ksoftirqd/0 5 root 0 -20 0 0 0 S 0,0 0,0 0:00.00 kworker/0:0H 6 root 20 0 0 0 0 S 0,0 0,0 0:00.00 kworker/u2:0 7 root 20 0 0 0 0 S 0,0 0,0 0:00.08 rcu_sched 8 root 20 0 0 0 0 S 0,0 0,0 0:00.00 rcu_bh 9 root rt 0 0 0 0 S 0,0 0,0 0:00.00 migration/0 10 root 0 -20 0 0 0 S 0,0 0,0 0:00.00 lru-add-drain (...) top allows the user some interaction. By default, the output is sorted by the percentage of CPU time used by each process in descending order. This behavior can be modified by pressing the following keys from within top: M Sort by memory usage. N Sort by process ID number. T Sort by running time. P Sort by percentage of CPU usage. Tip To switch between descending/ascending order just press R. Other interesting keys to interact with top are: ? or h Help. k Kill a process. top will ask for the PID of the process to be killed as well as for the signal to be sent (by default SIGTERM or 15). r Change the priority of a process (renice). top will ask you for the nice value. Possible values range from -20 through 19, but only the superuser (root) can set it to a value which is negative or lower than the current one. u List processes from a particular user (by default processes from all users are shown). c Show programs' absolute paths and differentiate between userspace processes and kernelspace processes (in square brackets). V Forest/hierarchy view of processes. t and m Change the look of CPU and memory readings respectively in a four-stage cycle: the first two presses show progress bars, the third hides the bar and the fourth brings it back. W Save configuration settings to ~/.toprc. Tip A fancier and more user-friendly version of top is htop. Another — perhaps more exhaustive — alternative is atop. If not already installed in your system, use your package manager to install them and give them a try. An Explanation of the output of top top output is divided into two areas: the summary area and the task area. The Summary Area in top The summary area is made up of the the five top rows and gives us the following information: top - 11:10:29 up 2:21, 1 user, load average: 0,11, 0,20, 0,14 current time (in 24-hour format): 11:20:29 uptime (how much time the system has been up and running): up 2:21 number of users logged in and load average of the CPU for the last 1, 5 and 15 minutes, respectively: load average: 0,11, 0,20, 0,14 Tasks: 73 total, 1 running, 72 sleeping, 0 stopped, 0 zombie (information about the processes) total number of processes in active mode: 73 total running (those being executed): 1 running sleeping (those waiting to resume execution): 72 sleeping stopped (by a job control signal): 0 stopped zombie (those which have completed execution but are still waiting for their parent process to remove them from the process table): 0 zombie %Cpu(s): 0,0 us, 0,3 sy, 0,0 ni, 99,7 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st (percentage of CPU time spent on) user processes: 0,0 us system/kernel processes: 0,4 sy processes set to a nice value — the nicer the value, the lower the priority: 0,0 ni nothing — idle CPU time: 99,7 id processes waiting for I/O operations: 0,0 wa processes serving hardware interrupts — peripherals sending the processor signals that require attention: 0,0 hi processes serving software interrupts: 0,0 si processes serving other virtual machine’s tasks in a virtual environment, hence steal time: 0,0 st KiB Mem : 1020332 total, 909492 free, 38796 used, 72044 buff/cache (memory information in kilobytes) the total amount of memory: 1020332 total unused memory: 909492 free memory in use: 38796 used the memory which is buffered and cached to avoid excessive disk access: 72044 buff/cache Notice how the total is the sum of the other three values — free, used and buff/cache — (roughly 1 GB in our case). KiB Swap: 1046524 total, 1046524 free, 0 used. 873264 avail Mem (swap information in kilobytes) the total amount of swap space: 1046524 total unused swap space: 1046524 free swap space in use: 0 used the amount of swap memory that can be allocated to processes without causing more swapping: 873264 avail Mem The Task Area in top: Fields and Columns Below the summary area there comes the task area, which includes a series of fields and columns reporting information about the running processes: PID Process identifier. USER User who issued the command that generated the process. PR Priority of process to the kernel. NI Nice value of process. Lower values have a higher priority than higher ones. VIRT Total amount of memory used by process (including Swap). RES RAM memory used by process. SHR Shared memory of the process with other processes. S Status of process. Values include: S (interruptible sleep — waiting for an event to finish), R (runnable — either executing or in the queue to be executed) or Z (zombie — terminated child processes whose data structures have not yet been removed from the process table). %CPU Percentage of CPU used by process. %MEM Percentage of RAM used by process, that is, the RES value expressed as a percentage. TIME+ Total time of activity of process. COMMAND Name of command/program which generated the process. Viewing processes statically: ps As said above, ps shows a snapshot of processes. To see all processes with a terminal (tty), type ps a: $ ps a PID TTY STAT TIME COMMAND 386 tty1 Ss+ 0:00 /sbin/agetty --noclear tty1 linux 424 tty7 Ssl+ 0:00 /usr/lib/xorg/Xorg :0 -seat seat0 (...) 655 pts/0 Ss 0:00 -bash 1186 pts/0 R+ 0:00 ps a (...) An Explanation of ps Option Syntax and Output Concerning options, ps can accept three different styles: BSD, UNIX and GNU. Let us see how each of these styles would work when reporting information about a particular process ID: BSD Options do not follow any leading dash: $ ps p 811 PID TTY STAT TIME COMMAND 811 pts/0 S 0:00 -su UNIX Options do follow a leading dash: $ ps -p 811 PID TTY TIME CMD 811 pts/0 00:00:00 bash GNU Options are followed by double leading dashes: $ ps --pid 811 PID TTY TIME CMD 811 pts/0 00:00:00 bash In all three cases, ps reports information about the process whose PID is 811 — in this case, bash. Similarly, you can use ps to search for the processes started by a particular user: ps U carol (BSD) ps -u carol (UNIX) ps --user carol (GNU) Let us check on the processes started by carol: $ ps U carol PID TTY STAT TIME COMMAND 811 pts/0 S 0:00 -su 898 pts/0 R+ 0:00 ps U carol She started two processes: bash (-su) and ps (ps U carol). The STAT column tells us the state of the process (see below). We can get the best out of ps by combining some of its options. A very useful command (producing an output similar to that of top) is ps aux (BSD style). In this case, processes from all shells (not only the current one) are shown. The meaning of the switches are the following: a Show processes that are attached to a tty or terminal. u Display user-oriented format. x Show processes that are not attached to a tty or terminal. $ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 204504 6780 ? Ss 14:04 0:00 /sbin/init root 2 0.0 0.0 0 0 ? S 14:04 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S 14:04 0:00 [ksoftirqd/0] root 5 0.0 0.0 0 0 ? S< 14:04 0:00 [kworker/0:0H] root 7 0.0 0.0 0 0 ? S 14:04 0:00 [rcu_sched] root 8 0.0 0.0 0 0 ? S 14:04 0:00 [rcu_bh] root 9 0.0 0.0 0 0 ? S 14:04 0:00 [migration/0] (...) Let us explain the columns: USER Owner of process. PID Process identifier. %CPU Percentage of CPU used. %MEM Percentage of physical memory used. VSZ Virtual memory of process in KiB. RSS Non-swapped physical memory used by process in KiB. TT Terminal (tty) controlling the process. STAT Code representing the state of process. Apart from S, R and Z (that we saw when describing the output of top), other possible values include: D (uninterruptible sleep — usually waiting for I/O), T (stopped — normally by a control signal). Some extra modifier include: < (high-priority — not nice to other processes), N (low-priority — nice to other processes), or + (in the foreground process group). STARTED Time at which the process started. TIME Accumulated CPU time. COMMAND Command that started the process. Guided Exercises oneko is a nice funny program that displays a cat chasing your mouse cursor. If not already installed in your desktop system, install it using your distribution’s package manager. We will use it to study job control. Start the program. How do you do that? Move the mouse cursor to see how the cat chases it. Now suspend the process. How do you do that? What is the output? Check how many jobs you currently have. What do you type? What is the output? Now send it to the background specifying its job ID. What is the output? How can you tell the job is running in the background? Finally, terminate the job specifying its job ID. What do you type? Discover the PIDs of all the processes spawned by the Apache HTTPD web server (apache2) with two different commands: Terminate all apache2 processes without using their PIDs and with two different commands: Suppose you have to terminate all instances of apache2 and you do not have time to find out what their PIDs are. How would you accomplish that using kill with the default SIGTERM signal in a one-liner: Start top and interact with it by performing the following: Show a forest view of processes: Show full paths of processes differentiating between userspace and kernelspace: Type the ps command to display all processes started by the Apache HTTPD web server user (www-data): Using BSD syntax: Using UNIX syntax: Using GNU syntax: Explorational Exercises The SIGHUP signal can be used as a way to restart certain daemons. With the Apache HTTPD web server — for example — sending SIGHUP to the parent process (the one started by init) kills off its children. The parent, however, re-reads its configuration files, re-opens log files and spawns a new set of children. Do the following tasks: Start the web server: Make sure you know the PID of the parent process: Make the Apache HTTPD web server restart by sending it the SIGHUP signal to the parent process: Check that the parent was not killed and that new children have been spawned: Although initially static, the output of ps can be turned dynamic by combining ps and watch. We will monitor the Apache HTTPD web server for new connections. Before doing the tasks described below it is recommended that you read the description of the MaxConnectionsPerChild directive in Apache MPM Common Directives. Add the MaxConnectionsPerChild directive with a value of 1 in the configuration file of apache2 — in Debian and derivatives that is found in /etc/apache2/apache2.conf; in the CentOS family, in /etc/httpd/conf/httpd.conf. Do not forget to restart apache2 for the changes to take effect. Type in a command that uses watch, ps and grep for apache2 connections. Now open a web browser or use a command line browser such as lynx to establish a connection to the web server through its IP address. What do you observe in the output of watch? As you have learned, by default top sorts the tasks by percentage of CPU usage in descending order (the higher values on top). This behaviour can be modified with the interactive keys M (memory usage), N (process unique identifier), T (running time) and P (percentage of CPU time). However, you can also sort the task list to your liking by launching top with the -o switch (for more information, check top’s man page). Now, perform the following tasks: Launch top so that the tasks are sorted by memory usage: Verify that you typed the right command by highlighting the memory column: ps also has an o switch to specify the columns you want shown. Investigate this option and do the following tasks: Launch ps so that only information about user, percentage of memory used, percentage of CPU time used and full command is shown: Now, launch ps so that the only information displayed is that of the user and the name of the programs they are using: Summary In this lesson you have learned about jobs and job control. Important facts and concepts to bear in mind are: Jobs are processes that are sent to the background. Apart from a process ID, jobs are also assigned a job ID when created. To control jobs, a job specification (jobspec) is required. Jobs can be brought to the foreground, sent to the background, suspended and terminated (or killed). A job can be detached from the terminal and session in which it was created. Likewise, we have also discussed the concept of processes and process monitoring. The most relevant ideas are: Processes are running programs. Processes can be monitored. Different utilities allow us to find out the process ID of processes as well as to send them signals to terminate them. Signals can be specified by name (e.g. -SIGTERM), number (e.g. -15) or option (e.g. -s SIGTERM). top and ps are very powerful when it comes to monitoring processes. The output of the former is dynamic and keeps updating constantly; on the other hand, ps reveals output statically. Commands used in this lesson: jobs Display active jobs and their status. sleep Delay for a specific amount of time. fg Bring job to the foreground. bg Move job to the background. kill Terminate job. nohup Detach job from session/terminal. exit Exit current shell. tail Display most recent lines in a file. watch Run a command repeatedly (2 seconds cycle by default). uptime Display how long the system has been running, the number of current users and system load average. free Display memory usage. pgrep Look up process ID based on name. pidof Look up process ID based on name. pkill Send signal to process by name. killall Kill process(es) by name. top Display Linux processes. ps Report a snapshot of the current processes. Answers to Guided Exercises oneko is a nice funny program that displays a cat chasing your mouse cursor. If not already installed in your desktop system, install it using your distribution’s package manager. We will use it to study job control. Start the program. How do you do that? By typing oneko into the terminal. Move the mouse cursor to see how the cat chases it. Now suspend the process. How do you do that? What is the output? By pressing the key combo Ctrl+z: [1]+ Stopped oneko Check how many jobs you currently have. What do you type? What is the output? $ jobs [1]+ Stopped oneko Now send it to the background specifying its job ID. What is the output? How can you tell the job is running in the background? $ bg %1 [1]+ oneko & The cat is moving again. Finally, terminate the job specifying its job ID. What do you type? $ kill %1 Discover the PIDs of all the processes spawned by the Apache HTTPD web server (apache2) with two different commands: $ pgrep apache2 or $ pidof apache2 Terminate all apache2 processes without using their PIDs and with two different commands: $ pkill apache2 or $ killall apache2 Suppose you have to terminate all instances of apache2 and you do not have time to find out what their PIDs are. How would you accomplish that using kill with the default SIGTERM signal in a one-liner: $ kill $(pgrep apache2) $ kill `pgrep apache2` or $ kill $(pidof apache2) $ kill `pidof apache2` Note Since SIGTERM (15) is the default signal, it is not necessary to pass any options to kill. Start top and interact with it by performing the following: Show a forest view of processes: Press V. Show full paths of processes differentiating between userspace and kernelspace: Press c. Type the ps command to display all processes started by the Apache HTTPD web server user (www-data): Using BSD syntax: $ ps U www-data Using UNIX syntax: $ ps -u www-data Using GNU syntax: $ ps --user www-data Answers to Explorational Exercises The SIGHUP signal can be used as a way to restart certain daemons. With the Apache HTTPD web server — for example — sending SIGHUP to the parent process (the one started by init) kills off its children. The parent, however, re-reads its configuration files, re-opens log files and spawns a new set of children. Do the following tasks: Start the web server: $ sudo systemctl start apache2 Make sure you know the PID of the parent process: $ ps aux | grep apache2 The parent process is that started by the root user. In our case the one with PID 1653. Make the Apache HTTPD web server restart by sending it the SIGHUP signal to the parent process: $ kill -SIGHUP 1653 Check that the parent was not killed and that new children have been spawned: $ ps aux | grep apache2 Now you should see the parent apache2 process together with two new children. Although initially static, the output of ps can be turned dynamic by combining ps and watch. We will monitor the Apache HTTPD web server for new connections. Before doing the tasks described below it is recommended that you read the description of the MaxConnectionsPerChild directive in Apache MPM Common Directives. Add the MaxConnectionsPerChild directive with a value of 1 in the config file of apache2 — in Debian and derivatives that is found in /etc/apache2/apache2.conf; in the CentOS family, in /etc/httpd/conf/httpd.conf. Do not forget to restart apache2 for the changes to take effect. The line to include in the config file is MaxConnectionsPerChild 1. One way to restart the web server is through sudo systemctl restart apache2. Type in a command that uses watch, ps and grep for apache2 connections. $ watch 'ps aux | grep apache2' or $ watch "ps aux | grep apache2" Now open a web browser or use a command line browser such as lynx to establish a connection to the web server through its IP address. What do you observe in the output of watch? One of the child processes owned by www-data disappears. As you have learned, by default top sorts the tasks by percentage of CPU usage in descending order (the higher values on top). This behaviour can be modify with the interactive keys M (memory usage), N (process unique identifier), T (running time) and P (percentage of CPU time). However, you can also sort the task list to your liking by launching top with the -o switch (for more information, check top’s man page). Now, do the following tasks: Launch top so that the tasks are sorted by memory usage: $ top -o %MEM Verify that you typed the right command by highlighting the memory column: Press x. ps has also an o switch to specify the columns you want shown. Investigate about this and do the following tasks: Launch ps so that only information about user, percentage of memory used, percentage of CPU time used and full command is shown: $ ps o user,%mem,%cpu,cmd Now, launch ps so that the only information displayed is that of the user and the name of the programs they are using: $ ps o user,comm