Linux перезапустить процесс по pid

Обновлено: 04.07.2024

Под процессом мы будем понимать запущенную в системе копию программы. Например, если вы открыли три окна калькулятора (например, gcalctool), это значит, что вы запустили три процесса.

Находим PID зависшего процесса

Каждый процесс в Linux имеет свой идентификатор, называемый PID. Перед тем, как выполнить остановку процесса, нужно определить его PID. Для этого воспользуемся командами ps и grep. Команда ps предназначена для вывода списка активных процессов в системе и информации о них. Команда grep запускается одновременно с ps (в канале) и будет выполнять поиск по результатам команды ps. Вывести список всех процессов можно, выполнив в командной строке:

Но, как правило, список очень большой и найти процесс, который мы хотим «убить», бывает не так просто. Здесь на помощь приходит команда grep. Например, чтобы найти информацию о процессе с именем gcalctool выполните команду:

Команда grep выполнит поиск по результатам команды ps и на экран будут выведены только те строки, которые содержат строку (слово) gcalctool. Здесь есть одна интересная деталь, например, если у вас не запущено приложение gcalctool, то после выполнения ps axu | grep gcalctool вы получите:

То есть мы получили сам процесс grep, так как в качестве параметра команде мы указали слово gcalctool, и grep нашел сам себя в выводе команды ps.

Если процесс gcalctool запущен, то мы получим:

Здесь нас интересует строка: «yuriy 25609 7.6 0.4 500840 17964 ? Sl 10:20 0:00 gcalctool». Число 25609 и есть идентификатор (PID) процесса gcalctool.

Есть еще один более простой способ узнать PID процесса — это команда pidof, которая принимает в качестве параметра название процесса и выводит его PID. Пример выполнения команды pidof:

«Убиваем» процесс командой kill

Когда известен PID процесса, мы можем убить его командой kill. Команда kill принимает в качестве параметра PID процесса. Например, убьем процесс с номером 25609:

Вообще команда kill предназначена для посылки сигнала процессу. По умолчанию, если мы не указываем какой сигнал посылать, посылается сигнал SIGTERM (от слова termination — завершение). SIGTERM указывает процессу на то, что необходимо завершиться. Каждый сигнал имеет свой номер. SIGTERM имеет номер 15. Список всех сигналов (и их номеров), которые может послать команда kill, можно вывести, выполнив kill -l. Чтобы послать сигнал SIGKILL (он имеет номер 9) процессу 25609, выполните в командой строке:

Сигнал SIGTERM может и не остановить процесс (например, при перехвате или блокировке сигнала), SIGKILL же выполняет уничтожение процесса всегда, так как его нельзя перехватить или проигнорировать.

Убиваем процессы командой killall

Команда killall в Linux предназначена для «убийства» всех процессов, имеющих одно и то же имя. Это удобно, так как нам не нужно знать PID процесса. Например, мы хотим закрыть все процессы с именем gcalctool. Выполните в терминале:

Команда killall, также как и kill, по умолчанию шлет сигнал SIGTERM. Чтобы послать другой сигнал нужно воспользоваться опцией -s. Например:

Заключение

Некоторые процессы не удается остановить под обычным пользователем. Например, если процесс был запущен от имени пользователя root или от имени другого пользователя системы, то команды kill и killall нужно выполнять от имени суперпользователя, добавляя sudo (в Ubuntu):

Бывают ситуации, когда вы работаете в графическом интерфейсе (например, GNOME) и вам не удается открыть эмулятор терминала, чтобы остановить зависший процесс. Тогда можно переключиться на виртуальную консоль клавишами Ctrl+Alt+F1, залогиниться в ней и выполнять команды уже из нее. А потом перейти обратно, нажав Ctrl+Alt+F7.

Список процессов

Вывести на экран список текущих процессов, запущенных пользователем, можно командой:

Чтобы посмотреть список всех процессов с дополнительной информацией, вводим:

Мы увидим, примерно, следующее:

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 661 0.0 0.0 4072 8 tty1 Ss+ Jul03 0:00 /sbin/mingetty
root 662 0.0 0.0 4072 8 tty2 Ss+ Jul03 0:00 /sbin/mingetty
root 16355 0.0 0.0 171636 3308 pts/0 S 15:46 0:00 sudo su
root 16366 0.0 0.0 140896 1556 pts/0 S 15:46 0:00 su
root 16368 0.0 0.0 108316 1944 pts/0 S 15:46 0:00 bash
root 18830 0.0 0.0 110244 1172 pts/0 R+ 16:20 0:00 ps u

  • USER — учетная запись пользователя, от которой запущен процесс.
  • PID — идентификатор процесса.
  • %CPU — потребление процессорного времени в процентном эквиваленте.
  • %MEM — использование памяти в процентах.
  • VSZ — Virtual Set Size. Виртуальный размер процесса (в килобайтах).
  • RSS — Resident Set Size. Размер резидентного набора (количество 1K-страниц в памяти).
  • TTY — терминал, из под которого был запущен процесс.
  • STAT — текущее состояние процесса. Могут принимать значения:
    1. R — выполнимый процесс;
    2. S — спящий;
    3. D — в состоянии подкачки на диске;
    4. T — остановлен;
    5. Z — зомби.
    6. W — не имеет резидентных страниц;
    7. < — высоко-приоритетный;
    8. N — низко-приоритетный;
    9. L — имеет страницы, заблокированные в памяти.
  • START — дата запуска процесса.
  • TIME — время запуска процесса.
  • COMMAND — команда, запустившая процесс.

Ключи

Ключ Описание
-A Все процессы.
-a Запущенные в текущем терминале, кроме главных системных.
-d Все, кроме главных системных процессов сеанса.
-e Все процессы.
f Показать дерево процессов с родителями.
T Все на конкретном терминале.
a Все, связанные с текущим терминалом и терминалами других пользователей.
r Список только работающих процессов.
x Отсоединённые от терминала.
u Показать пользователей, запустивших процесс.

Примеры

Поиск процесса с помощью grep:

ps aux | grep apache

Убить процесс

Останавливаем процесс по его PID:

Если процесс не завершается, убиваем его принудительно:

Остановить все процессы с именем nginx:

Как и в случае с kill, можно это сделать принудительно:

killall -9 nginx

Ищем процесс по имени, извлекаем его PID и завершаем его:

* обратите внимание, что запрос может вывести несколько процессов, которые будут попадать под критерии поиска — в таком случае, они будут завершены все.

Подробная информация о процессе

Для каждого процесса создается каталог по пути /proc/<PID>, в котором создаются папки и файлы с описанием процесса.

Примеры использования /proc/<PID>

Подробный вывод статуса:

Адрес в ячейках оперативной памяти, которые занял процесс:

Команда, которой был запущен процесс:

Символьная ссылка на рабочий каталог процесса:

Символьная ссылка на исполняемый файл, запустивший процесс:

Увидеть ссылки на дескрипторы открытых файлов, которые затрагивает процесс:

Потребление ресурсов процессами

Для просмотра статистики потребления ресурсов используем утилиту top:

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
21059 root 20 0 157884 2280 1496 R 18,8 0,1 0:00.03 top
1 root 20 0 190996 2964 1652 S 0,0 0,1 6:49.99 systemd
2 root 20 0 0 0 0 S 0,0 0,0 0:01.78 kthreadd
3 root 20 0 0 0 0 S 0,0 0,0 0:24.75 ksoftirqd/0
5 root 0 -20 0 0 0 S 0,0 0,0 0:00.00 kworker/0:0H


У меня есть две системы Linux, которые обмениваются данными через сокеты (настольный компьютер и плата разработки на базе ARM).

Я не могу понять, как это нужно делать.

Обычный способ сделать это - позволить программе выйти и перезапустить ее с помощью системы мониторинга. В init программа предлагает такую ​​систему мониторинга. Существует множество различных программ инициализации (SysVinit, BusyBox, Systemd и т. Д.) С совершенно разными механизмами конфигурации (всегда записывается файл конфигурации, но расположение и синтаксис файла различаются), поэтому поищите документацию к той, которую вы Использую. Настройте init для запуска вашей программы во время загрузки или по явному запросу и для перезапуска, если она умирает. Существуют также более интересные программы мониторинга, но, похоже, они вам не нужны. Этот подход имеет много преимуществ по сравнению с перезапуском программы самостоятельно: он стандартный, поэтому вы можете перезапустить несколько служб, не заботясь о том, как они созданы; он работает, даже если программа умирает из-за ошибки.

Есть стандартный механизм, который сообщает процессу о завершении: сигналы. Отправьте вашей программе сигнал TERM. Если вашей программе необходимо выполнить какую-либо очистку, напишите обработчик сигнала. Это не исключает наличия специальной команды для ее выключения, если у вас есть административный канал для отправки ей подобных команд.

Этот restart.c работает так:

Если клиентское приложение является службой Linux, его можно перезапустить с помощью этой команды:

или принудительно перезагрузить его конфигурацию:

Если, что более вероятно, это настраиваемое приложение, ему необходимо встроить в свой код функцию, чтобы перезапустить себя или перезагрузить свою конфигурацию при получении сигнала или события. Если этого не сделать, в крайнем случае вы всегда можете убить клиентское приложение:

и снова перезапустите, но это некрасиво, поскольку оно оставляет приложение в неопределенном состоянии.

  • 1 Если приложение уже не находится в фиктивном состоянии, -9 аргумент pkill не требуется, неиспользование должно позволить приложению полностью остановиться.
  • @ dr01 Если приложение не является сервисом, то как его перезапустить?
  • @SaadRafey: это написано в моем ответе, возможность перезапуска себя чисто или перезагрузить конфигурацию должна быть прописана в коде.
  • Я думаю, это работает только со СТАРЫМИ версиями UBUTNU
  • @noone Вовсе нет, это стандартная команда SystemV для управления службами. Это правда, что большинство современных версий дистрибутивов используют Systemd.

Я сделал функцию для выполнения команды в оболочке:

Затем, чтобы убить процесс и перезапустить его, я использовал:

Я использовал команду nohup, потому что она освобождает терминал после выполнения команды. Теперь, чтобы вызвать запуск этого сценария, вы можете написать в основном потоке программы:

По инерции вы движетесь дальше. Что это за SIGHUP такой, и как его посылают? Вы почти уверены, что это не команда, но, на всякий случай, пробуете. Нет, не то. Перечитываем ман к приложению:

Когда получен сигнал о том, что программа зависла - SIGHUP, sshd перечитывает свой конфигурационный файл путем запуска самой себя с теми же именем и опциями, с которыми была первоначально запущена, например, /usr/sbin/sshd.

Программисты против пользователей

Авторы страниц руководств (манов) делятся на две категории. Одни адресуются конечным пользователям, а другие - "крутым" программистам. Вот почему встречаются заявления типа: "список do будет в работе до тех пор, пока последняя команда в этом списке не выдаст ненулевой выходной статус" . Прочитать такое также приятно и полезно, как и "пошлите процессу SIGHUP". Не переживайте, сегодня мы прольем свет на эти тайны, покрытые мраком.

Сигналы и контроль над процессами

Одной из задач опытных администраторов и пользователей является запуск, остановка и перезапуск сервисов, а также остановка сбойных и зависших процессов, причем с минимальным уроном. В различных операционных системах, а также в различных командных оболочках (шеллах) способы управления сигналами сильно рознятся. Поэтому в этой статье мы остановимся на ОС Linux и bash shell.

Все демоны и процессы имеют Идентификатор Процесса (PID). PID процесса можно узнать при помощи команды ps:

В приведенном выше примере, вывод команды сильно сокращен - в вашей системе вы увидите куда больше строк и столбцов. Если какой-нибудь процесс "ворует" мощность вашего процессора или вашу память, вы увидите это в столбцах %CPU и %MEM.

Еще быстрее "зарвавшийся" процесс можно обнаружить при помощи команды top. В ней, по умолчанию, процессы, потребляющие больше ресурсов процессора, расположены в верхних строках таблицы. Мы можем немного поиграть с программой top при помощи команды yes:

$ yes carla is teh awesum

Эта команда станет повторять "carla is teh awesum" с большой скоростью, пока вы ее не остановите. Она загонит процент использования процессора в красную зону:

Интересно, что ответственность за разбазаривание мощности CPU ложится на консоль, а не на программу yes, так как yes работает внутри консоли. Если вы перейдете на "истинную" консоль (Ctrl+Alt+F2), то там увидите программу yes с большими цифрами потребления мощности процессора и использования памяти.

Существует несколько способов остановить yes. Если вы перейдете обратно в шелл, где она работает, просто нажмите Ctrl+C. Вы можете также остановить ее при помощи команды kill в другом шелле, как по PID, так и по имени:

$ kill 22236
$ killall yes

Ctrl+C посылает с клавиатуры сигнал SIGINT (2), или завершающее прерывание (terminate interrupt). kill и killall, оба, шлют по умолчанию SIGTERM (15). SIGTERM (15) может быть перехвачен и, либо игнорирован, либо интерпретирован иначе. Так что, в случае непредсказуемой работы, вы можете не добиться завершения процесса.

Применяя команду kill к родительскому процессу, вы, как правило (но не всегда), завершаете дочерний вместе с ним. Как узнать, какой процесс является дочерним? Используйте команду ps с опцией -f :

Вернемся к нашим SIGHUP'ам

SIGHUP произносится как "сиг-ап" и означает "сигнал отбоя" (signal hangup). Как послать SIGHUP? Существует несколько способов:

Как видите, можно использовать PID или имя процесса, а также имя или номер сигнала.

Зачем применять все эти команды, когда можно перезапустить процессы при помощи команды /etc/init.d/foo restart? Ведь предпочтительней контролировать сервисы с помощью их файлов init, так как такой контроль обычно включает санацию, проверку ошибок и другие функции. Если говорить честно, то главная причина использовать команду kill и сигналы состоит в том, чтобы остановить зависший или сбойный процесс как можно аккуратнее, и не прибегать к перезагрузке или завершению сеанса.

Применение команды kill к процессам

Как можно видеть в man signal, существуют десятки способов контролировать процессы. Вот наиболее часто применяемые:

kill -STOP 'pid'
SIGSTOP (19) останавливает процесс, не "убивая" его.

kill -CONT 'pid'
SIGCONT (18) перезапускает остановленный процесс.

kill -KILL 'pid'
SIGKILL (9) форсирует немедленное завершение процесса, и не производит никакой чистки.

kill -9 -1
Завершает все ваши процессы (которыми вы владеете).

SIGKILL и SIGSTOP не могут быть перехвачены, блокированы или игнорированы; остальные могут. Это ваше "большое ружье", последнее средство обороны.

Команда kill, встроенная в Bash

Оболочка Bash имеет встроенную команду kill, как показано в следующем листинге:

$ type -all kill
kill is a shell built-in
kill is /bin/kill

Маловероятно, что у вас возникнут конфликты или странное поведение программ, но на всякий случай выбирайте /bin/kill.

Не поленитесь получше познакомиться с большим миром команды kill, изучив приведенные ниже ресурсы. Это предоставит вам возможность решать возникающие проблемы путем тонкого хирургического вмешательства, не прибегая к перезагрузке системы при каждом сбое программы.

Читайте также: