13.2 Управление процессами (Managing Processes)¶
Управление выполняющимися процессами — одна из ключевых задач администратора Linux. В данном разделе мы рассмотрим, как это делается. Будут затронуты следующие темы:
- Запуск системных процессов
- Просмотр выполняющихся процессов
- Назначение приоритетов процессам
- Управление процессами на переднем и фоновом планах
- Завершение выполняющегося процесса
- Сохранение процесса после выхода из системы
Начнём с изучения запуска процессов.
Запуск системных процессов (Starting System Processes)¶
Существует два основных способа запустить процесс в Linux. Для пользовательского процесса (user process) достаточно ввести имя команды или сценария в командной строке. Например, чтобы запустить программу vi, нужно просто ввести vi в командной строке. При этом создаётся процесс vi, как показано здесь:
Для системных процессов (system processes) используется либо сценарий init, либо служебный файл — в зависимости от того, применяет ли ваш дистрибутив процесс init или systemd. Если в дистрибутиве используется процесс init, то при загрузке системы он задействует сценарии init для запуска процессов. Эти сценарии хранятся в определённом каталоге системы Linux, который зависит от конкретного дистрибутива. Большинство дистрибутивов Linux используют один из двух типов сценариев init:
-
System V Дистрибутивы Linux, использующие сценарии System V init, хранят их в каталоге
/etc/rc.d. Внутри/etc/rc.dнаходится ряд подкаталогов с именами отrc0.dдоrc6.d. Каждый из этих каталогов соответствует определённому уровню выполнения. Внутри каждого подкаталога находятся символьные ссылки на сценарии init системных демонов, которые расположены в/etc/rc.d/init.d. -
BSD Другие дистрибутивы Linux используют сценарии init в стиле BSD. Эти сценарии располагаются в каталоге
/etc/init.d. Внутри/etc/init.dнаходится ряд каталогов с именами отrc0.dдоrc6.d. Как и в случае сценариев System V init, эти каталоги привязаны к определённым уровням выполнения. Они содержат ссылки на сценарии init в/etc/init.d.
Помимо запуска этих сценариев через процесс init, их можно запускать непосредственно из командной строки. Для этого нужно ввести /etc/init.d/имя_сценария (для систем в стиле BSD) или /etc/rc.d/init.d/имя_сценария (для систем в стиле System V). Если вы не знаете нужное имя сценария, можно воспользоваться командой ls для получения списка сценариев в каталоге. Это показано на рисунке 13-6.

Рис. 13-6. Сценарии init в каталоге /etc/init.d.
Набор сценариев в вашем каталоге init зависит от того, какие службы вы установили. Каждый раз при установке службы с помощью утилиты rpm соответствующий сценарий init автоматически помещается в каталог сценариев init. После этого любой сценарий можно запустить непосредственно из командной строки. Синтаксис (для систем в стиле BSD) выглядит следующим образом:
Например, чтобы запустить службу smb, нужно ввести /etc/init.d/smb start в командной строке. Для остановки — /etc/init.d/smb stop. Для перезапуска — /etc/init.d/smb restart.
В некоторых дистрибутивах для запуска, остановки или перезапуска служебного процесса можно также использовать сценарий rc без указания полного пути к файлу сценария. Синтаксис: rcимя_сценария start | stop | restart. Например, чтобы запустить службу smb, можно ввести rcsmb start в командной строке. Для остановки — rcsmb stop. Можно также использовать параметр restart для перезапуска.
Если в вашем дистрибутиве Linux вместо init используется процесс systemd, то управление системными службами осуществляется с помощью служебных файлов с расширением .service. Для запуска, остановки, перезапуска и проверки состояния служб используется команда systemctl:
- Для запуска службы введите
systemctl start имя_службы. - Для остановки службы введите
systemctl stop имя_службы. - Для перезапуска службы введите
systemctl restart имя_службы. - Для просмотра состояния службы введите
systemctl status имя_службы.
Например, чтобы включить демон sshd в дистрибутиве с systemd, нужно ввести systemctl start sshd в командной строке.
Теперь, когда вы знаете, как запускать и останавливать системные процессы, перейдём к просмотру выполняющихся процессов.
Просмотр выполняющихся процессов (Viewing Running Processes)¶
В этой части раздела мы рассмотрим, как просматривать выполняющиеся процессы в системе. Будут рассмотрены следующие инструменты:
- Использование
top - Использование
ps - Использование
free - Использование
pgrep
Начнём с утилиты top.
Использование top (Using top)¶
Linux предоставляет широкий выбор инструментов для просмотра выполняющихся процессов. Одним из наиболее удобных является утилита top. Она запускается простым вводом top в командной строке. После запуска отображается интерфейс, показанный на рисунке 13-7.

Рис. 13-7. Использование top для просмотра выполняющихся процессов.
Как видно на рисунке 13-7, top отображает список выполняющихся процессов — по одному на каждой строке. Для отображения информации о каждом процессе используются следующие столбцы:
- PID Идентификатор процесса (PID).
- USER Имя пользователя, которому принадлежит процесс.
- PR Приоритет, назначенный процессу. (Приоритеты процессов будут рассмотрены далее в этой главе.)
- NI Значение «вежливости» процесса (nice value). (Что это означает — будет объяснено далее.)
- VIRT Объём виртуальной памяти, используемой процессом.
- RES Объём физической оперативной памяти, используемой процессом (резидентный размер), в килобайтах.
- SHR Объём разделяемой памяти, используемой процессом.
- S Состояние процесса. Возможные значения:
- D Непрерываемый сон (Uninterruptibly sleeping)
- R Выполняется (Running)
- S Ожидание (Sleeping)
- T Трассировка или остановка (Traced or stopped)
- Z Зомби (Zombied)
Примечание
Процесс-зомби (zombied process) — это процесс, который завершил выполнение, но родительский процесс не получил уведомления о его завершении и не освободил PID дочернего процесса. Процесс-зомби может в конечном счёте самоустраниться. Если этого не происходит, может потребоваться принудительно завершить родительский процесс. Как это сделать — будет рассмотрено далее в главе.
- %CPU Процент времени ЦП, используемого процессом.
- %MEM Процент доступной физической оперативной памяти, используемой процессом.
- TIME+ Общее время ЦП, потреблённое процессом с момента запуска.
- COMMAND Имя команды, введённой для запуска процесса.
Главное достоинство top — динамичность. Экран постоянно обновляется, отражая актуальное состояние каждого процесса. Можно также сортировать информацию. Нажав клавишу h во время работы top, вы откроете экран справки с перечнем клавиш для сортировки по различным категориям. Этот экран показан на рисунке 13-8.

Рис. 13-8. Экран справки top.
Этот экран также показывает, как использовать другие параметры top. Например, можно нажать f, чтобы отобразить список столбцов, которые можно добавить в вывод, как показано на рисунке 13-9.

Рис. 13-9. Добавление столбцов в вывод top.
Поля, которые будут отображаться, обозначены звёздочкой (*). Чтобы добавить или убрать поле, нужно перейти к нему стрелками и нажать пробел. Это переключает наличие звёздочки. Кроме того, можно нажать u, чтобы отображались только процессы, связанные с конкретным пользователем.
Утилита top очень удобна. Единственный её недостаток — она отображает только ограниченное число процессов. Иногда требуется увидеть все процессы, выполняющиеся в системе. В такой ситуации top не подходит, и нужно использовать утилиту ps.
Использование ps (Using ps)¶
Утилита ps позволяет отображать выполняющиеся процессы в системе. В отличие от top, которая показывает процессы динамически, ps выдаёт снимок текущих выполняющихся процессов.
Просто введя ps, можно просмотреть процессы, связанные с текущей оболочкой, как показано здесь:
openSUSE:~ # ps
PID TTY TIME CMD
3946 pts/1 00:00:00 su
3947 pts/1 00:00:00 bash
3994 pts/1 00:00:00 ps
В этом примере ps отображает следующие процессы:
- su Утилита
suиспользуется в этой оболочке для переключения на учётную запись суперпользователя root. - bash Текущий сеанс оболочки
bash. - ps Поскольку
psиспользуется для вывода списка текущих процессов, её собственный процесс также включается в список.
По умолчанию отображается следующая информация:
- PID Идентификатор процесса.
- TTY Имя терминальной сессии (оболочки), в которой выполняется процесс.
- TIME Объём времени ЦП, использованного процессом.
- CMD Имя команды, введённой для создания процесса.
Обратите внимание, что в списке оказалось только три процесса. На той системе, где выполнялась приведённая выше команда, выполнялось значительно больше процессов: в отдельной оболочке работал top, а также X-сервер и среда рабочего стола GNOME. Почему они не попали в список? По умолчанию ps показывает только процессы, связанные с текущей оболочкой. Поэтому в списке отображаются только оболочка, su и ps.
Чтобы увидеть все процессы, выполняющиеся в системе, нужно использовать параметр -e совместно с ps. Пример:
openSUSE:~ # ps –e
PID TTY TIME CMD
1 ? 00:00:06 systemd
2 ? 00:00:00 kthreadd
3 ? 00:00:00 ksoftirqd/0
5 ? 00:00:00 kworker/0:0H
7 ? 00:00:00 migration/0
8 ? 00:00:00 rcuc/0
9 ? 00:00:00 rcub/0
10 ? 00:00:01 rcu_preempt
11 ? 00:00:00 rcu_bh
12 ? 00:00:00 rcu_sched
13 ? 00:00:00 watchdog/0
14 ? 00:00:00 watchdog/1...
Как видно из этого примера, параметр -e приводит к отображению значительно большего числа процессов. Кроме того, обратите внимание, что у большинства показанных процессов в столбце TTY стоит знак ?. Это означает, что процесс является системным. Системные процессы (демоны) загружаются процессом init или systemd при запуске системы и потому не привязаны ни к какой оболочке. Именно поэтому в столбце TTY вывода ps для них отображается ?.
Можно также заметить, что объём отображаемой информации в ps довольно невелик по сравнению с top. Используя параметр -f совместно с ps, можно получить более подробный вывод. В следующем примере параметры -e и -f используются вместе для отображения расширенной информации о каждом процессе, выполняющемся в системе:
openSUSE:~ # ps –ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 17:41 ? 00:00:06 /sbin/init showopts
root 2 0 0 17:41 ? 00:00:00 [kthreadd]
root 3 2 0 17:41 ? 00:00:00 [ksoftirqd/0]
root 5 2 0 17:41 ? 00:00:00 [kworker/0:0H]
root 7 2 0 17:41 ? 00:00:00 [migration/0]
root 8 2 0 17:41 ? 00:00:00 [rcuc/0]
root 9 2 0 17:41 ? 00:00:00 [rcub/0]
root 10 2 0 17:41 ? 00:00:01 [rcu_preempt]
root 11 2 0 17:41 ? 00:00:00 [rcu_bh]
root 12 2 0 17:41 ? 00:00:00 [rcu_sched]
root 13 2 0 17:41 ? 00:00:00 [watchdog/0]
root 14 2 0 17:41 ? 00:00:00 [watchdog/1]...
С параметром -f становится доступна дополнительная информация, включая:
- UID Идентификатор пользователя-владельца процесса.
- PPID Идентификатор родительского процесса (PID).
- C Объём времени процессора, использованного процессом.
- STIME Время запуска процесса.
Для получения ещё более подробного вывода можно использовать параметр -l совместно с командой ps. Параметр -l отображает «длинный» формат вывода ps. Пример:
openSUSE:~ # ps –efl
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
1 S root 2 0 0 80 0 - 0 kthrea 11:09 ? 00:00:00 [kth]
1 S root 3 2 0 -40 - - 0 migrat 11:09 ? 00:00:00 [mig]
1 S root 4 2 0 80 0 - 0 run_ks 11:09 ? 00:00:00 [kso]
5 S root 5 2 0 -40 - - 0 watchd 11:09 ? 00:00:00 [wat]
1 S root 6 2 0 -40 - - 0 migrat 11:09 ? 00:00:00 [mig]
1 S root 7 2 0 80 0 - 0 run_ks 11:09 ? 00:00:00 [kso]
5 S root 8 2 0 -40 - - 0 watchd 11:09 ? 00:00:00 [wat]
1 S root 9 2 0 80 0 - 0 worker 11:09 ? 00:00:00 [eve]
1 S root 10 2 0 80 0 - 0 worker 11:09 ? 00:00:00 [eve]
1 S root 11 2 0 80 0 - 0 worker 11:09 ? 00:00:00 [net]
...
С параметром -l доступна следующая информация о выполняющихся процессах:
- F Флаги, связанные с процессом. В этом столбце используются следующие коды:
- 1 Ветвление выполнено, но exec не вызван
- 4 Использованы привилегии суперпользователя root
- S Состояние процесса. В этом столбце используются следующие коды:
- D Непрерываемое ожидание (Uninterruptible sleep)
- R Выполняется (Running)
- S Прерываемое ожидание (Interruptible sleep)
- T Остановлен или трассируется (Stopped or traced)
- Z Зомби (Zombied)
- PRI Приоритет процесса.
- NI Значение «вежливости» процесса. (Что это означает — будет объяснено в следующем разделе.)
- ADDR Адрес памяти процесса.
- SZ Размер процесса.
- WCHAN Имя функции ядра, в которой находится процесс в состоянии ожидания. Если процесс в данный момент выполняется, в этом столбце отображается дефис (
–).
Использование free (Using free)¶
Управление процессами в системе Linux подразумевает знание о том, сколько памяти используется и сколько её доступно. Как было сказано ранее, для просмотра этой информации можно использовать вывод top.
Также можно воспользоваться командой free. Команда free отображает объём свободной и выделенной оперативной памяти и памяти подкачки в системе. Параметр -m позволяет отображать статистику памяти в мегабайтах. Параметр -t отображает итоговые суммы по каждой категории информации. В следующем примере использована команда free –mt для просмотра статистики памяти:
openSUSE:~ # free –mt
total used free shared buffers cached
Mem: 1507 620 887 4 29 243
-/+ buffers/cache: 347 1160
Swap: 2053 0 2053
Total: 3561 620 2941
Использование pgrep (Using pgrep)¶
Команда ps очень полезна для просмотра информации о процессах. Однако её вывод иногда бывает чрезмерно объёмным, особенно если требуется найти один или два конкретных процесса. Один из вариантов — направить вывод ps в команду grep и отобразить только результаты, соответствующие заданным критериям.
Другой вариант — использовать команду pgrep. Как следует из её названия, pgrep объединяет функциональность команд ps и grep в одной утилите. При запуске pgrep задаются критерии отбора. Затем команда просматривает все выполняющиеся процессы и выводит список процессов, соответствующих этим критериям. Для формирования критериев отбора доступны следующие параметры:
-P ppid— поиск по указанному PID родительского процесса.-f name— поиск по указанному имени процесса.-u user_name— поиск по указанному владельцу процесса.
По умолчанию вывод pgrep содержит только PID совпавших процессов. Чтобы отобразить также имя процесса, нужно использовать параметр -l. Например, чтобы просмотреть список всех процессов, принадлежащих пользователю rtracy, можно использовать следующую команду:
openSUSE:~ # pgrep -l -u rtracy
3262 systemd
3264 (sd-pam)
3266 gnome-keyring-d
3269 gnome-session
3319 dbus-launch
3320 dbus-daemon
3322 ibus-daemon
3347 gvfsd
...
Теперь, когда вы знаете, как просматривать выполняющиеся процессы, перейдём к вопросу назначения приоритетов процессам.
Назначение приоритетов процессам (Prioritizing Processes)¶
Напомним, что Linux является многозадачной операционной системой. Она распределяет время ЦП между всеми выполняющимися процессами, создавая иллюзию их одновременного выполнения.
Поскольку Linux — это многозадачная операционная система, для каждого процесса можно задать уровень приоритета. Это определяет, сколько времени ЦП получит данный процесс относительно других.
По умолчанию Linux старается равномерно распределять время ЦП между всеми процессами. Однако иногда требуется скорректировать приоритет конкретного процесса. В зависимости от конфигурации системы может потребоваться предоставить определённому процессу более высокий приоритет по сравнению с остальными. Для этого существует ряд утилит Linux. В данной части главы будут рассмотрены следующие инструменты:
- Установка приоритетов с помощью
nice - Изменение приоритетов выполняющихся процессов с помощью
renice
Начнём с изучения утилиты nice.
Установка приоритетов с помощью nice (Setting Priorities with nice)¶
Утилита nice позволяет запустить программу с отличным от стандартного уровнем приоритета. Напомним из предыдущего обсуждения top и ps, что каждый выполняющийся процесс имеет связанные с ним значения PR и NI. Это показано на рисунке 13-10.

Рис. 13-10. Просмотр значений PR и NI.
Значение PR — это приоритет процесса с точки зрения ядра. Чем выше число, тем ниже приоритет процесса. Чем ниже число, тем выше приоритет. Значение NI — это значение «вежливости» (nice value) процесса. Оно учитывается в расчётах ядра при определении приоритета процесса. Значение «вежливости» для любого процесса Linux может находиться в диапазоне от –20 до +19. Чем ниже значение «вежливости», тем выше приоритет процесса.
Напрямую изменить приоритет процесса нельзя, но можно изменить его значение «вежливости». Проще всего сделать это при первоначальном запуске команды, создающей процесс. Для этого используется команда nice. Синтаксис: nice –n уровень_вежливости команда.
Например, предположим, что требуется запустить программу vi с повышенным приоритетом, уменьшив её значение «вежливости» до –5. До этого vi выполняется с приоритетом 80, как показано здесь:
Обратите внимание, что у процесса vi значение «вежливости» по умолчанию равно 0. Ядро использует это значение для вычисления общего приоритета процесса, который равен 80. Можно повысить приоритет этого процесса, введя nice –n –15 vi в командной строке. После этого значения приоритета и «вежливости» процесса vi уменьшатся, что означает повышение его приоритета в системе. Это показано в следующем примере:
Обратите внимание, что значение «вежливости» уменьшилось до –15. В результате общий приоритет процесса снизился до значения 65.
Следует учитывать, что Linux ограничивает возможность уменьшения значения «вежливости» для процессов. Поскольку Linux — многопользовательская операционная система, несколько пользователей могут одновременно изменять значения «вежливости» своих процессов. Разумеется, каждый пользователь считает свои процессы важнее остальных и может быть соблазнён установить значение «вежливости» –20 для почти всего, что он запускает.
Чтобы этого не происходило, Linux не разрешает снижать значение «вежливости» процесса ниже 0, если вы не вошли в систему как root. Иными словами, без прав суперпользователя использование отрицательных чисел с командой nice недоступно.
Команда nice отлично подходит для изменения значения «вежливости» при запуске команды. Но что делать, если нужно изменить приоритет уже выполняющегося процесса? В этом случае nice не подходит — нужно использовать команду renice.
Изменение приоритетов выполняющихся процессов с помощью renice (Setting Priorities of Running Processes with renice)¶
Вместо того чтобы завершать процесс и перезапускать его с другим значением «вежливости» через nice, можно использовать команду renice для изменения значения «вежливости» уже выполняющегося процесса. Синтаксис: renice значение_вежливости PID.
Например, в приведённом выше примере PID процесса vi равен 8488. Чтобы понизить приоритет этого процесса без его выгрузки, можно ввести renice 4 8488 в командной строке, как показано в следующем примере:
openSUSE:~ # renice 4 8488
8488: old priority -15, new priority 4
openSUSE:~ # ps -elf | grep vi
4 S root 8488 8455 0 84 4 - 6533 - 08:40 pts/0 00:00:00 vi
Как видно из этого примера, значение «вежливости» процесса vi увеличилось с –15 до 4. В результате общий приоритет процесса вырос с 65 до 84, то есть его приоритет в системе снизился. Так же как и с nice, для установки отрицательного значения «вежливости» выполняющегося процесса необходимо быть вошедшим в систему как root.
Перейдём к обсуждению процессов на переднем и фоновом планах.
Управление процессами на переднем и фоновом планах (Managing Foreground and Background Processes)¶
В данной части главы будет рассмотрен запуск процессов на переднем (foreground) и фоновом (background) планах. Будут рассмотрены следующие темы:
- Запуск процессов в фоновом режиме
- Переключение процессов между фоновым и передним планами
Запуск процессов в фоновом режиме (Running Processes in the Background)¶
Как было сказано ранее, при вводе любой команды в командной строке создаётся субоболочка и процесс выполняется в ней. Как только процесс завершается, субоболочка уничтожается. Пока процесс выполняется, приглашение командной строки родительской оболочки недоступно. Нельзя ничего вводить в командной строке, если только не открыть новый терминальный сеанс.
Это происходит потому, что процесс выполняется на переднем плане (foreground). Такое поведение особенно очевидно при запуске графического приложения из командной строки. На рисунке 13-11 приложение LibreOffice было запущено из командной строки командой libreoffice.

Рис. 13-11. Запуск графического приложения на переднем плане.
Обратите внимание на рисунке 13-11, что курсор в оболочке недоступен. Он останется недоступным до закрытия LibreOffice. Только после этого можно будет вводить дополнительные команды в этой командной строке.
Это поведение по умолчанию для всех команд, вводимых в командной строке, — как для текстовых программ оболочки, так и для графических программ. Однако программу можно запустить в фоновом режиме (background). При этом запущенная программа будет работать в обычном режиме, но управление сразу же вернётся к оболочке. Затем из оболочки можно запускать другие программы или выполнять другие задачи.
Запуск программы в фоновом режиме — очень простая операция. Достаточно добавить к команде символ амперсанда (&). Это указывает оболочке запустить программу в фоновом режиме. На рисунке 13-12 приложение LibreOffice снова запущено, но на этот раз к концу команды добавлен амперсанд, что приводит к его запуску в фоновом режиме.

Рис. 13-12. Запуск приложения в фоновом режиме.
Обратите внимание на рисунке 13-12, что после запуска процесса в фоновом режиме на экране отобразились два значения. Первое значение, [1], — идентификатор фонового задания (background job ID), присвоенного
фоновому заданию. Второе значение — PID процесса. Просмотреть все фоновые задания, выполняющиеся в системе, можно командой jobs:
В этом примере вывод команды jobs отображает состояние задания и имя команды, которая была запущена для создания фонового задания.
Переключение процессов между фоновым и передним планами (Switching Processes Between the Background and the Foreground)¶
То, что процесс был запущен на фоновом или переднем плане, не означает, что он должен там и оставаться. Можно переключать процесс между передним и фоновым планами во время его выполнения. Для этого используются следующие команды:
- fg Эта команда переводит фоновый процесс на передний план. Синтаксис:
fg идентификатор_задания. - bg Эта команда переводит процесс с переднего плана в фоновый режим. Для этого сначала нужно назначить процессу на переднем плане идентификатор фонового задания. Это делается нажатием
ctrl-z. После этого процесс останавливается и ему назначается идентификатор фонового задания. Затем можно ввестиbg идентификатор_заданиядля перевода процесса в фоновый режим.
В следующем примере программа vi была загружена в обычном режиме на переднем плане, затем остановлена с помощью ctrl-z, при этом ей был присвоен идентификатор задания 1. Затем она была отправлена в фоновый режим командой bg 1:
Завершение выполняющегося процесса (Ending a Running Process)¶
К этому моменту в главе было рассмотрено практически всё, что можно делать с процессами в Linux: их загрузка, просмотр, назначение приоритетов, перемещение в фоновый режим и на передний план. Единственная задача, которую мы ещё не рассмотрели, — как завершить выполняющийся процесс.
Обычно для завершения выполняющегося процесса используется функция exit, встроенная почти во все программы. Например, в vi для выхода из редактора вводится :exit. Однако иногда процессы зависают и, несмотря на все усилия, не закрываются корректно. В такой ситуации может потребоваться принудительно завершить зависший процесс. Это можно сделать двумя способами:
- С помощью
killиkillall - С помощью
pkill
Рассмотрим сначала использование команды kill.
Использование kill и killall (Using kill and killall)¶
Команда kill используется для завершения процесса. Синтаксис: kill –сигнал PID. Параметр PID — это идентификатор процесса, который нужно завершить. Также можно отправить процессу конкретный сигнал завершения. Всего существует около 64 различных типов сигналов. Наиболее полезные из них:
- SIGHUP Это сигнал kill номер 1. Данный сигнал перезапускает процесс. После перезапуска процесс получает точно такой же PID, как и до этого. Это очень полезный параметр для перезапуска службы после внесения изменений в её конфигурационный файл.
- SIGINT Это сигнал kill номер 2. Данный сигнал посылает процессу последовательность клавиш
ctrl-c. - SIGKILL Это сигнал kill номер 9. Это «грубый» сигнал, принудительно завершающий процесс. Если процесс сильно завис, данный параметр заставит его остановиться. Однако при использовании этого сигнала процесс может не выполнить корректное завершение. Ресурсы, выделенные процессу, могут оставаться занятыми до перезагрузки системы.
- SIGTERM Это сигнал kill номер 15. Данный сигнал предписывает процессу немедленно завершить работу. Это сигнал по умолчанию, отправляемый командой
kill, если сигнал не указан явно. Этот сигнал позволяет процессу выполнить корректное завершение перед выходом.
При использовании kill можно указывать либо текстовое имя сигнала (например, SIGTERM), либо его номер (например, 15). Для использования kill сначала нужно с помощью ps или top определить PID процесса. В следующем примере процесс vi выполняется с PID 8312:
openSUSE:~ # ps
PID TTY TIME CMD
8278 pts/0 00:00:00 su
8279 pts/0 00:00:00 bash
8312 pts/0 00:00:00 vi
8313 pts/0 00:00:00 ps
openSUSE:~ # kill -SIGTERM 8312
openSUSE:~ #
В этом примере введена команда kill –SIGTERM 8312 для завершения процесса vi. Можно было также ввести kill –15 8312 и получить тот же результат. Поскольку сигнал SIGTERM позволяет процессу освободить ресурсы перед выходом, процесс vi завершается корректно.
Это подводит к типичной ошибке начинающих администраторов Linux при работе с kill: они сразу прибегают к самому жёсткому сигналу, не пробуя более мягкие варианты. Да, SIGKILL сработает, но лучше сначала попробовать другие, более «чистые» сигналы. Только если они не помогут, стоит прибегнуть к более жёсткому сигналу. Рекомендуемая последовательность действий при зависшем процессе:
- Сначала отправьте SIGINT. Если процесс не реагирует, перейдите к шагу 2.
- Отправьте SIGTERM. Обычно это решает проблему и позволяет процессу завершиться корректно. Если нет — перейдите к шагу 3.
- Отправьте SIGKILL.
Помимо kill, для завершения процессов можно использовать команду killall. Команда killall очень похожа на kill, синтаксис практически идентичен. Ключевое отличие состоит в том, что killall использует имя команды процесса, а не его PID. Например, если нужно завершить процесс vi из предыдущего примера с помощью killall вместо kill, нужно ввести killall –15 vi. Эта команда отправляет сигнал SIGTERM процессу с именем vi.
Настоятельно рекомендуется ознакомиться со страницей руководства для killall. Она весьма обширна и содержит полезную информацию. Например, там показано, как с помощью параметра -u завершать процессы, принадлежащие конкретному пользователю.
Использование pkill (Using pkill)¶
Помимо kill и killall, для остановки выполняющегося процесса можно использовать команду pkill. Команда pkill является «родственником» команды pgrep, рассмотренной ранее. Они используют одинаковые параметры и даже имеют общую страницу руководства.
С помощью pkill можно искать процессы, соответствующие заданным критериям, и отправлять им определённый сигнал завершения. Например, чтобы найти все выполняющиеся процессы с именем vi и отправить им сигнал SIGTERM, нужно ввести pkill -SIGTERM -f vi в командной строке.
Сохранение процесса после выхода из системы (Keeping a Process Running After Logout)¶
Последняя тема, которую мы рассмотрим в этом разделе, — как сохранить запущенный процесс после выхода из системы. Как уже обсуждалось, сигналы могут отправляться выполняющимся процессам для уведомления о системных событиях.
Широко используется сигнал разрыва соединения — SIGHUP (hang-up signal). Linux отслеживает, какие процессы запущены в каком терминальном сеансе. При выходе пользователя из терминального сеанса Linux отправляет сигнал SIGHUP всем программам, связанным с этим сеансом.
Обычно каждый процесс реагирует на SIGHUP ожидаемым образом. Однако можно настроить процесс на игнорирование сигналов SIGHUP, что позволит ему продолжать выполнение даже после завершения сеанса оболочки. Для этого используется утилита nohup. Это заставляет процесс, созданный командой, игнорировать все сигналы SIGHUP.
Например, предположим, что создан сценарий оболочки updatemydb, который автоматически обновляет базу данных из внешнего источника данных. Выполнение этого сценария занимает много времени (обычно всю ночь), и оставлять систему с активным сеансом на это время нежелательно. Можно ввести nohup updatemydb & в командной строке и затем выйти из системы. Если команда генерирует вывод, который обычно направляется в stdout, nohup перенаправит его в файл ~/nohup.out.
Важно отметить, что команда, запущенная под nohup, защищена только от сигналов SIGHUP. Все остальные сигналы завершения по-прежнему работают. Например, программу можно завершить во время её выполнения с помощью сигнала SIGTERM и команды kill.
Аналогичной командой является screen. Команда screen — интересная утилита, особенно полезная при удалённом доступе к системе Linux через SSH-соединение. Ключевое преимущество screen — возможность использовать несколько окон оболочки в рамках одного SSH-сеанса. Например, если запустить top удалённо в SSH-сеансе, то из-за особенностей работы SSH-клиента нельзя вводить другие команды до остановки top и возврата к командной строке, если не открывать несколько SSH-сеансов.
Используя screen, можно держать top запущенным, одновременно работая в командной строке через SSH-соединение и вводя дополнительные команды. Это особенно ценно тем, что screen может поддерживать активность SSH-сеанса даже при разрыве сетевого соединения. Можно даже отключаться и повторно подключаться к сеансу оболочки из разных мест, не останавливая и не перезапуская выполняемые процессы.
Прежде чем использовать screen, нужно убедиться, что он установлен в системе. Большинство дистрибутивов включают его по умолчанию, но некоторые — нет.
После установки screen запускается простым вводом screen в командной строке. При этом отображается экран приветствия с информацией о лицензии и использовании, который нужно пройти. После этого отобразится командная строка — внешне она выглядит обычно, но теперь вы находитесь внутри окна screen. Это окно функционирует как обычный сеанс оболочки: в нём можно выполнять команды и взаимодействовать с программами точно так же, как из любой другой командной строки.
Однако если нажать ctrl-a, то всё, что вводится после этого, передаётся команде screen, а не оболочке. Примеры:
- Нажатие
ctrl-a, затем?отображает справку поscreen. - Нажатие
ctrl-a, затемcсоздаёт новое окноscreen. Предыдущее окно остаётся активным вместе со всеми запущенными в нём процессами. Например, если в окнеscreenв SSH-сеансе выполнялсяtop, а нужно проверить почту, не останавливаяtop, можно открыть новое окно и работать с почтой, покаtopпродолжает работать в первом окне. - Нажатие
ctrl-a, затемnпереключает между открытыми окнамиscreen. - Нажатие
ctrl-a, затемdотсоединяет (detach) текущее окноscreenи возвращает в исходную командную строку. При этом всё, что выполнялось в окне, продолжает работу. Можно даже полностью выйти из сервера — всё будет продолжать работать в отсоединённом окне. - Ввод
screen –rповторно подключает к отсоединённому окнуscreen. При наличии нескольких отсоединённых окон будет предложено выбрать, к какому из них подключиться.
Упражнение 13-1. Работа с процессами Linux (Exercise 13-1: Working with Linux Processes)¶
Упражнение 13-1. Работа с процессами Linux
В этом упражнении вы будете практиковаться в использовании команд оболочки для управления процессами в системе. Упражнение можно выполнить на виртуальной машине, поставляемой с этой книгой. Для правильно настроенной среды запустите снимок 13-1.
Совет
Посмотрите видеозапись упражнения 13-1 для ознакомления с порядком выполнения задания.
Выполните следующее:
- Загрузите систему Linux и войдите как обычный пользователь.
- Откройте терминальный сеанс.
- Переключитесь на учётную запись суперпользователя root, введя
su –и парольstudent. - Потренируйтесь в запуске системных процессов:
a. В командной строке введите
systemctl status atd. Каков статус демонаat? (В большинстве дистрибутивов демонatdпо умолчанию не настроен для запуска.) b. Запустите демонatd, введяsystemctl start atdв командной строке. c. Снова введитеsystemctl status atdв командной строке. Службаatdдолжна теперь отображаться как запущенная. - Потренируйтесь в использовании
top: a. В командной строке введитеtop. b. Просмотрите список выполняющихся процессов. c. Нажмитеhдля перехода к экрану справкиtop. Какая клавиша сортирует вывод по статистике ЦП? d. Нажмитеtдля сортировки по статистике ЦП. Какие процессы используют больше всего времени ЦП в вашей системе? e. Нажмитеmдля сортировки по использованию памяти. Какие процессы потребляют больше всего памяти? f. Добавьте столбцы, нажавf. g. Добавьте столбец PPID, нажавb, затем пробел. Теперь в выводе должен появиться PPID каждого процесса. h. Выйдите изtop, нажавq. - Потренируйтесь в использовании утилиты
psдля просмотра процессов: a. В командной строке введитеps. Какие процессы связаны с текущим сеансом оболочки? b. Просмотрите все выполняющиеся процессы в системе, введяps –ef | moreв командной строке. c. Нажимайте пробел, пока не найдёте службуatd. Под каким именем пользователя выполняетсяatd? (В большинстве дистрибутивов — под пользователемat.) d. В командной строке введитеps –el | less. e. Найдите столбец состояния (S). f. Нажимайте пробел, пока не найдёте службуatd. Каков статус службы? (Поскольку она сейчас не используется, скорее всего, она находится в состоянии ожидания.) - Потренируйтесь в управлении приоритетами процессов:
a. В командной строке введите
top. b. Каковы значения приоритета (PR) и «вежливости» (NI) для процессаtop? (В большинстве дистрибутивов — 16 и 0.) c. Нажмитеqдля остановкиtop. d. В командной строке введитеnice –n –20 top. Каковы теперь значения PR и NI для процессаtop? e. Запишите PID процессаtop. f. Откройте новое окно терминала и войдите какroot. g. В командной строке измените значение «вежливости» работающегоtop, введяrenice 1 PID_top. h. Переключитесь обратно в первый терминал, где запущенtop. Каковы теперь его значения PR и NI? i. Нажмитеqдля выхода изtop. - Потренируйтесь в переключении процессов между передним и фоновым планами:
a. Снова запустите
top, введяtopв командной строке. b. В терминале с запущеннымtopнажмитеctrl-z. c. Запишите номер идентификатора фонового задания, присвоенного процессу. d. В командной строке введитеbg идентификатор_фонового_задания. Выводtopисчезнет, пока процесс выполняется в фоновом режиме. e. Нажмитеctrl-c. f. В командной строке введитеfg идентификатор_фонового_задания. Выводtopснова появится, когда процесс перейдёт на передний план. - Потренируйтесь в завершении процессов:
a. Убедитесь, что
topпо-прежнему выполняется. b. Переключитесь в другой терминал, где вы вошли какroot. c. В командной строке введитеps –e | grep top. d. Запишите PID процессаtop. e. В командной строке введитеkill –SIGTERM PID_top. f. Переключитесь обратно в терминал, где выполнялсяtop. Убедитесь, чтоtopзавершился. g. Снова запуститеtopв командной строке. h. Переключитесь обратно в другой терминал, где вы вошли какroot. i. Завершите процессtop, введяkillall –15 top. j. Переключитесь обратно в первое окно терминала и убедитесь, чтоtopзавершился. - Потренируйтесь в использовании
screen: a. При необходимости введитеexitдля возврата к обычной учётной записи пользователя. b. Нажмите Enter для выхода из экрана приветствия. c. В командной строке окнаscreenвведитеtop. d. Нажмитеctrl-a, затемcдля создания нового окна. e. В командной строке нового окна введитеpgrep –l –f top.topдолжен по-прежнему выполняться, и его PID будет отображён. f. Нажмитеctrl-a, затемn. Вы должны переключиться обратно в окно с запущеннымtop. g. Нажмитеctrl-a, затемdдля отсоединения текущего окна. h. Повторно подключитесь к окну с запущеннымtop, введяscreen –rв командной строке. Окноtopдолжно снова отобразиться. i. Выйдите изtop, нажав Esc, затем выйдите изscreen, введяexit.