Контроль над процесами
Кожна розпочата програма називається процесом. Ці процеси сягають від Віконної Системи 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)
.