Контроль над процесами

Кожна розпочата програма називається процесом. Ці процеси сягають від Віконної Системи X до системних програм (демонів), запущених під час старту системи. Кожний процес діє від імені певного користувача, ті що започатковано під час завантаження системи, як правило, запущені від імені root або nobody. Процеси, які ви розпочали, будуть числитись під вашим іменем.

Вам надається повний контроль над процесами, що ви започаткували, root користувачу - над всіма процесами, інших користувачів включно. Контроль над процесами і спостереження здійснюється за допомогою декількох програм і команд оболонки, розглянутих нижче.

Фонові процеси

Програми, запущені з командного рядка, як правило, залишаються на передньому плані. Це дозволяє бачити весь вивід програми і взаємодіяти з нею. Тим не менш, часто буває, що нам необхідно розпочати програму таким чином, щоб вона не блокувала нашого терміналу, тобто у фоновому режимі. Існує декілька способів добитися цього.

Під час запуску програми можна добавити знак кон'юнкції (&) в кінці командного рядка. Наприклад, ви вирішили використати програму ?amp(1) для того щоб прослухати каталог із mp3-файлами, але, одночасно, вам потрібен командний рядок для виконання інших завдань. Наступна команда запустить amp у фоновому режимі:

$ amp *.mp3 &

Іншим способом помістити програму у фоновий режим, це запустити її звичайно на передньому плані, тобто у пріоритетному режимі, потім притиснути комбінацію клавіш Ctrl+Z, яка призупиняє процес. Хоча процес і призупинено, його завжди можна знову запустити з того самого місця де його було перервано. Існує дві команди для цього: fg (скорочення для foreground) і bg (background). Щоб перезапустити процес у фоновому режимі, ми повинні виконати

[1]+  Stopped              amp *.mp3
$ bg

Тепер колишній процес переднього плану буде виконуватись у фоновому режимі.

Пріоритетні процеси

Як ми вже сказали, запуск програми без амперсанду (знака кон'юкції) залишить її на передньому плані. Якщо ж ви загнали процес у фоновий режим за допомогою одного з способів, перелічених у попередньому розділі, то можете видобути його на передній план командою

$ fg

Якщо процес дійсний, він візьме контроль над вашим терміналом. Іноді програми завершують свою роботу у фоновому режимі, у таких випадках ви отримаєте повідомлення на зразок:

[1]+  Done            amp *.mp3

Цілком можливо мати декілька процесів, запущених у фоновому режимі, одночасно. У таких випадках потрібно знати, який саме процес вивести назовні, сама по собі команда fg виведе на передній план лише останню команду, що було загнано у фоновий режим, це може бути не тим, що нас цікавить. Нам потрібно спочатку перечислити всі процеси у підгрунтті за допомогою вбудованої bash-команди jobs:

$ jobs
[1]   Stopped                 vim
[2]-  Stopped                 amp
[3]+  Stopped                 man ps

У цьому прикладі показано перелік процесів у фоновому режимі. Як ви бачите, вони всі позначені як "Stopped", тобто призупинені. Числа у квадратних дужках, це своєрідний ідентифікаційний номер процесів. Процес із знаком плюс (+) буде саме тим процесом, що звичайна fg виведе назовні. Щоб вивести якийсь інший з перечислених процесів, добавте ідентифікаційний номер після команди fg, наприклад для vim:

$ fg 1

Запуск програм у фоновому режимі дуже зручний у випадку ssh-з'єднань або використанню терміналів через даялап з'єднання, тощо. Ви можете запустити декілька програм одночасно і переходити від однієї до іншої у разі потреби.

ps

Крім процесів, запущених вами з командного рядка, існують також багато додаткових, включаючи постійні системні процеси. Команда ?ps(1) допоможе перелічити всі процеси, включаючи ті що не належать вам. Ця команда має багато додаткових опцій, ми розглянемо найважливіші. Для повного списку загляніть у сторінку посібника ?ps(1). Сама по собіps виведе список програм, запущених у поточному терміналі, включаючи пріоритетні процеси (разом із оболонкою, яку ви використовуєте і, звичайно, саму ps), фонові процеси також будуть перечислені. Частіше, це буде доволі коротким списком:

$ ps
   PID TTY          TIME CMD
  7923 ttyp0    00:00:00 bash
  8059 ttyp0    00:00:00 ps

Останнє є доволі типовим виводом команди ps. Розглянемо, що ці поля виводу означають.

PID (process ID) - кожному запущеному процесові надається унікальне ідентифікаційне число у діапазоні між 1 і 32767. Кожний процес, що започатковано отримає наступний вільний PID-номер. Якщо процес припиняє свою роботу або його вбито (дивіться kill команду у наступному підрозділі), він звільняє свій PID-номер. Коли досягнуто максимальної кількості номерів PID, призначення починається з нижчих звільнених чисел.

TTY-стовпчик вказує на якому терміналі запущено процес. Звичайна команда ps перечислить лише процеси, запущені на поточному терміналі, тож всі процеси містять ту саму інформацію у нашому прикладі у стовпчику TTY, тобто ttyp0 (цей термінал призначено для віддалений під'єднань або X-емуляторів терміналу).

TIME-стовпчик вказує скільки CPU-часу процес спожив. Цей час відрізнятиметься від фізичного часу. Пам'ятаймо, що Лінукс - це багатозадачна операційна система, багато процесів запущено водночас, кожному з яких може бути виділена лише маленька частка процесорного часу. Тож TIME-колонка покаже дійсний час, виділений процесором для окремих завдань. Якщо час у цій колонці перевищуватиме декілька хвилин, це може означати, що щось негаразд.

Накінець, CMD-колонка вказує на саму програму. Виводиться лише базова назва програми, без командних опцій і аргументів. Для того щоб отримати цю додаткову інформацію, вам необхідно буде вжити деякі додаткові прапорці ps, розглянуті нижче.

Ви можете отримати повний список процесів, запущених на вашій системі, за допомогою додаткових -ax або ax (без дефісу) опцій до ps, як показано у наступному прикладі (ми дещо скоротили вивід):

$ ps -ax
 PID TTY      STAT   TIME COMMAND
   1 ?        S      0:03 init [3]
   2 ?        SW     0:13 [kflushd]
   3 ?        SW     0:14 [kupdate]
   4 ?        SW     0:00 [kpiod]
   5 ?        SW     0:17 [kswapd]
  11 ?        S      0:00 /sbin/kerneld
  30 ?        SW     0:01 [cardmgr]
  50 ?        S      0:00 /sbin/rpc.portmap
  54 ?        S      0:00 /usr/sbin/syslogd
  57 ?        S      0:00 /usr/sbin/klogd -c 3
  59 ?        S      0:00 /usr/sbin/inetd
  61 ?        S      0:04 /usr/local/sbin/sshd
  63 ?        S      0:00 /usr/sbin/rpc.mountd
  65 ?        S      0:00 /usr/sbin/rpc.nfsd
  67 ?        S      0:00 /usr/sbin/crond -l10
  69 ?        S      0:00 /usr/sbin/atd -b 15 -l 1
  77 ?        S      0:00 /usr/sbin/apmd
  79 ?        S      0:01 gpm -m /dev/mouse -t ps2
 106 tty1     S      0:08 -bash
 108 tty3     SW     0:00 [agetty]
 109 tty4     SW     0:00 [agetty]
 110 tty5     SW     0:00 [agetty]
 111 tty6     SW     0:00 [agetty]
...

Ваш вивід може відрізнятися, в залежності від того які сервіси у вас запущені. Як бачите, деякі процеси показані з опціями командного рядка, тоді як інші мають опції прихованими (завдяки ptrace латці ядра, що приховує командні опції певних процесів).

Як ви, напевне, зауважили, для багатьох процесів у TTY-стовпчику вказано "?". Це означає що ці процеси не прив'язано до жодного терміналу. Це характерно для демонів, - сервісів, що виконуються у фоновому режимі. Найпоширенішими демонами є sendmail, BIND, Apache (httpd), NFS, cron, тощо. Як правило, останні очікують запитів від клієнтів і повертають характерну інформацію якщо запит здійснено.

Тут ми побачимо додаткову колонку під назвою STAT. STAT є скороченням від status (статус). Умовними позначеннями для статусів процесів є:

diS
: для сплячих (sleeping) процесів, що очікують якоїсь дії для активації.

Z : для зомбованих процесів (zombie), чиїх батьківський процес припинив свою роботу, залишивши за собою випадковий дочірній процес. Це, загалом, вважається поганою поведінкою програм.

D : позначатиме процеси що увійшли у стан сплячки без можливості переривання. Часто такі процеси відмовляються припинити своє існування, навіть після сигналу SIGKILL(описаному у наступному підрозділі).

W : означає ?поділ пам'яті на сторінки? (paging).

X
: позначатиме мертвий процес.

T
: процес, що відслідковується, трасується (traced) або зупинено.

R
: означає що процес активний (runable).

Якщо ви хочете отримати навіть більше інформації про процеси, спробуйте наступне:

$ ps -aux
 USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
 root         1  0.0  0.0   344   80 ?        S    Mar02   0:03 init [3]
 root         2  0.0  0.0     0    0 ?        SW   Mar02   0:13 [kflushd]
 root         3  0.0  0.0     0    0 ?        SW   Mar02   0:14 [kupdate]
 root         4  0.0  0.0     0    0 ?        SW   Mar02   0:00 [kpiod]
 root         5  0.0  0.0     0    0 ?        SW   Mar02   0:17 [kswapd]
 root        11  0.0  0.0  1044   44 ?        S    Mar02   0:00 /sbin/kerneld
 root        30  0.0  0.0  1160    0 ?        SW   Mar02   0:01 [cardmgr]
 bin         50  0.0  0.0  1076  120 ?        S    Mar02   0:00 /sbin/rpc.port
 root        54  0.0  0.1  1360  192 ?        S    Mar02   0:00 /usr/sbin/sysl
 root        57  0.0  0.1  1276  152 ?        S    Mar02   0:00 /usr/sbin/klog
 root        59  0.0  0.0  1332   60 ?        S    Mar02   0:00 /usr/sbin/inet
 root        61  0.0  0.2  1540  312 ?        S    Mar02   0:04 /usr/local/sbi
 root        63  0.0  0.0  1796   72 ?        S    Mar02   0:00 /usr/sbin/rpc.
 root        65  0.0  0.0  1812   68 ?        S    Mar02   0:00 /usr/sbin/rpc.
 root        67  0.0  0.2  1172  260 ?        S    Mar02   0:00 /usr/sbin/cron
 root        77  0.0  0.2  1048  316 ?        S    Mar02   0:00 /usr/sbin/apmd
 root        79  0.0  0.1  1100  152 ?        S    Mar02   0:01 gpm
 chris      106  0.0  0.5  1820  680 tty1     S    Mar02   0:08 -bash
 root       108  0.0  0.0  1048    0 tty3     SW   Mar02   0:00 [agetty]
 root       109  0.0  0.0  1048    0 tty4     SW   Mar02   0:00 [agetty]
 root       110  0.0  0.0  1048    0 tty5     SW   Mar02   0:00 [agetty]
 root       111  0.0  0.0  1048    0 tty6     SW   Mar02   0:00 [agetty]
...

Останнє додасть також інформацію про те, який саме користувач започаткував процес, яку долю системних ресурсів процес використовує (%CPU, %MEM, VSZ та RSS колонки), також дату коли процес було започатковано. Очевидно, що це достатньо інформації, цікавої системному адміністраторові. Може статися, що виведені рядки будуть занадто довгі і вийдуть за рамки екрану, в такому випадку можна вжити також ключ -w (wrap) для завертання довгих ліній.

Ви знайдете ще декілька опцій ps у сторінці посібника до цієї програми.

kill

Зрідка, програми поводяться не так як належить і вам необхідно якимось чином вплинути на них. Програмою для таких завдань являється kill(1), яка може впливати на перебіг процесів у декілька способів. Найбільш очевидне завдання kill - це знищити процес - буває необхідним коли останній зациклено і споживає всі системні ресурси.

Для того щоб знищити процес, вам необхідно знати PID, тобто ідентифікаційний номер процесу. Використайте команду ps, яку ми пройшли у попередньому розділі, для цього. Так, наприклад, щоб вбити процес під номером 4747, виконайте наступне:

$ kill 4747

Звичайно, ви повинні бути володарем цього процесу для того щоб його знищити. Це одна з рис безпеки системи, тож користувачі не можуть переривати процеси які їм не належать. root-користувач, як і очікується, може перервати будь-який процес.

Одним з різновидів kill є програма ?killall(1). Остання зупинить всі процеси з певною, наданою вами, назвою. Наприклад, якщо би ви хотіли вбити всі процеси під назвою mozilla-bin, командою було б:

$ killall mozilla-bin

Любі, запущені вами програми mozilla-bin, будуть припинені. Ця сама команда, виконана root-користувачем, вб'є всі процеси mozilla-bin усіх користувачів. Останнє приводить до цікавого способу викинути тимчасово всіх користувачів з системи, включаючи самого root-користувача, командою:

# killall bash

Іноді буває деякі програми відмовляються завершити свою роботу при використанні звичайної команди kill. В такому разі, необхідно використати агресивнішу форму kill:

$ kill -9 4747

Обидві kill і killall візьмуть як аргумент номер, що відповідає сигналу який можна послати процесові. Звичайна kill посилає більш цивілізований сигнал SIGTERM, що вказує процесові завершити роботу, очистити пам'ять і вийти, тоді як останньому прикладі -9 означатиме потужніший SIGKILL, що нагально перериває процес. Загалом, SIGKILL використовується лише в крайніх випадках, оскільки він може призвести до псування даних.

Ви можете отримати список всіх можливих сигналів за допомогою прапорця -l (англійська "л") (list):

$ 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  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

Крім номерів сигналів, також можна використовувати їхні назви без префіксу "SIG", наприклад:

$ killall -KILL xedit

Ще одним застосуванням kill буде рестарт процесів. Якщо ви пошлете сигнал SIGHUP програмі, вона рестартує, перечитавши власний конфігураційний файл, якщо такий є. Це особливо корисно для того щоб заставити системним процесам перечитати файли конфігурації після їхнього редагування.

top

Накінець, існує команда яку ви можете використати для виводу інформації що поновлюється з перебігом часу. Ця команда називається ?top(1) і запускається як:

$ top

Останнє виведе повний екран різноманітної інформації про активні процеси, також деякі додаткові дані про систему. Це включає середнє навантаження системи, кількість процесів, стан процесора, пам'яті, інформацію про, власне, процеси, включаючи ідентифікаційний номер (PID), пріоритет, скільки вони споживають процесора і пам'яті, час активності і назву програми.

 6:47pm  up 1 day,  18:01,  1 user,  load average: 0.02, 0.07, 0.02             
61 processes: 59 sleeping, 2 running, 0 zombie, 0 stopped                       
CPU states:  2.8% user,  3.1% system,  0.0% nice, 93.9% idle                    
Mem:   257992K av,  249672K used,    8320K free,   51628K shrd,  78248K buff    
Swap:   32764K av,     136K used,   32628K free,                 82600K cached  
PID USER    PRI  NI  SIZE  RSS  SHARE  STAT  LIB %CPU %MEM  TIME COMMAND        
 112 root     12   0 19376  18M   2468  R       0  3.7  7.5 55:53 X             
4946 root     12   0  1040 1040    836  R       0  1.5  0.4  0:00 top           
 121 david     4   0   796  796    644  S       0  1.1  0.3 25:37 wmSMPmon      
 115 david     3   0  2180 2180   1452  S       0  0.3  0.8  1:35 wmaker        
4948 david    16   0   776  776    648  S       0  0.3  0.3  0:00 xwd           
   1 root      1   0   176  176    148  S       0  0.1  0.0  0:13 init          
 189 david     1   0  6256 6156   4352  S       0  0.1  2.4  3:16 licq          
4734 david     0   0  1164 1164    916  S       0  0.1  0.4  0:00 rxvt          
   2 root      0   0     0    0      0  SW      0  0.0  0.0  0:08 kflushd       
   3 root      0   0     0    0      0  SW      0  0.0  0.0  0:06 kupdate       
   4 root      0   0     0    0      0  SW      0  0.0  0.0  0:00 kpiod         
   5 root      0   0     0    0      0  SW      0  0.0  0.0  0:04 kswapd        
  31 root      0   0   340  340    248  S       0  0.0  0.1  0:00 kerneld       
  51 root      0   0    48   48     32  S       0  0.0  0.0  0:00 dhcpcd        
  53 bin       0   0   316  316    236  S       0  0.0  0.1  0:00 rpc.portmap   
  57 root      0   0   588  588    488  S       0  0.0  0.2  0:01 syslogd       

Сама назва програми top вказує на те, що найбільш ресурсоємкі процеси будуть перечислені зверху. top досить ефективна для виявлення які програми погано поводяться і тому повинні бути зупиненими.

Якщо вас цікавлять лише процеси що належать певному користувачу, ви можете використати прапорець -u (user) з ім'ям користувача або його ідентифікаційним номером (UID):

$ top -u alan

top також підтримує відслідковування процесів за їхнім ідентифікаційним номером (PID), ігнорування пасивних (idle) і зомбі (zombie) процесів і ще багато додаткових опцій, про які ви можете дізнатися зі сторінки посібника ?top(1).