Как завершить фоновый процесс?

Вопрос или проблема

Я запустил wget на удаленной машине в фоновом режиме, используя &. Вдруг он перестал скачивать. Я хочу завершить этот процесс и затем снова запустить команду. Как я могу его завершить?

Я не закрыл окно оболочки. Но, как вы знаете, он не останавливается с помощью Ctrl+C и Ctrl+Z.

Существует множество способов сделать это.

Метод #1 – ps

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

Пример

$ ps -eaf | grep [w]get 
saml      1713  1709  0 Dec10 pts/0    00:00:00 wget ...

$ kill 1713

Метод #2 – pgrep

Вы также можете найти идентификатор процесса с помощью pgrep.

Пример

$ pgrep wget
1234

$ kill 1234

Метод #3 – pkill

Если вы уверены, что это единственный запущенный вами wget, вы можете использовать команду pkill, чтобы убить задачу по имени.

Пример

$ pkill wget

Метод #4 – jobs

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

Пример

Моя фальшивая задача, sleep.

$ sleep 100 &
[1] 4542

Найдите номер задания. ПРИМЕЧАНИЕ: число 4542 — это идентификатор процесса.

$ jobs
[1]+  Запущено                 sleep 100 &

$ kill %1
[1]+  Завершено              sleep 100

Метод #5 – fg

Вы можете вернуть задание из фона в передний план, используя команду fg.

Пример

Фальшивая задача, sleep.

$ sleep 100 &
[1] 4650

Получите номер задания.

$ jobs
[1]+  Запущено                 sleep 100 &

Верните задачу #1 в передний план, а затем используйте Ctrl+C.

$ fg 1
sleep 100
^C
$

В bash вы можете использовать fg, чтобы вернуть задание на передний план, а затем использовать Ctrl+C.

Или выведите список процессов в фоновом режиме с помощью jobs, а затем выполните

kill %1

(где 1 заменяется номером, который дал вам jobs)

Также вы можете использовать kill $!, чтобы убить последнее задание, запущенное в фоновом режиме.

ИЗМЕНЕНИЕ: Оказавшись на переднем плане, вы можете Ctrl+C, или, как упоминает @Zelda, убить с помощью ‘%x’, где ‘x’ — это номер задания, что вызовет сигнал по умолчанию (скорее всего, SIGTERM в случае Linux).

Просто введите fg, чтобы вернуть его на передний план, если это был последний процесс, который вы отправили в фон (с помощью ‘&’).

Если это не был последний, введите: jobs и найдите ‘номер задания’, представленный в ‘[]’. Затем просто введите:

fg 2

..где ‘2’ — это номер задания, например:

foo@bar:~/junk/books$ jobs
[1]+  Запущено                 okular how_to_cook_a_turkey.pdf &
foo@bar:~/junk/books$ fg 1
okular how_to_cook_a_turkey.pdf            <- это теперь на переднем плане.

Это старая проблема, и уже есть несколько хороших ответов, но я постараюсь представить свой немного другим способом.

На самом деле, фоновые процессы называются задачами, а управление заданиями очень хорошо объясняется на этих 3 коротких страницах: https://www.gnu.org/software/bash/manual/html_node/Job-Control.html

В основном, мы можем ссылаться на задачу с помощью jobspec, то есть символа %, за которым следует либо другой символ (или последовательность в некоторых более сложных случаях), либо идентификатор задания. И это то же самое для kill, fg, bg или disown.

  • %+ (или просто %, или %%) будет ссылаться на последнюю отправленную в фон
    задачу (текущую)
  • %- будет ссылаться на предыдущую
  • %{jobid} будет ссылаться на указанную задачу

Чтобы перечислить ваши фоновые задачи, вы используете команду jobs.

Примечание

kill $! имеет другое поведение, он убивает последний процесс, отправленный в фон в качестве задачи, а не последнюю созданную задачу.

например

Вы отправили 5 задач в фон.

Вы возвращаете задачу #2 на передний план (fg %2, или просто %2), затем отправляете ее обратно в фон (<Ctrl-Z>, затем bg).

Это последний процесс, отправленный в фон, но он остается задачей #2.

Таким образом, kill $! завершит задачу #2 — последний (повторно)отправленный в фон процесс, тогда как kill %+ убьет задачу #5, последнюю созданную задачу (“текущая задача”):

$ jobs
[1]   Запущено                 sleep 1000 &
[2]   Запущено                 sleep 2000 &
[3]   Запущено                 sleep 3000 &
[4]-  Запущено                 sleep 4000 &
[5]+  Запущено                 sleep 5000 &
$ fg %2
sleep 2000
^Z
[2]+  Остановлено                 sleep 2000
$ bg
[2]+ sleep 2000 &
$ jobs
[1]   Запущено                 sleep 1000 &
[2]   Запущено                 sleep 2000 &
[3]   Запущено                 sleep 3000 &
[4]-  Запущено                 sleep 4000 &
[5]+  Запущено                 sleep 5000 &
$ kill %+
$ jobs
[1]   Запущено                 sleep 1000 &
[2]   Запущено                 sleep 2000 &
[3]   Запущено                 sleep 3000 &
[4]-  Запущено                 sleep 4000 &
[5]+  Завершено              sleep 5000
$ kill $!
[2]   Завершено              sleep 2000
$ jobs
[1]   Запущено                 sleep 1000 &
[3]-  Запущено                 sleep 3000 &
[4]+  Запущено                 sleep 4000 &

Одна вещь, которую я не вижу здесь, которую я нашел очень полезной, особенно при тестировании команд, это pidof. Вы можете использовать pidof [команда], чтобы найти идентификатор процесса запущенного процесса. Мне это нравится, потому что это позволяет быстро найти идентификатор команды, которую я хочу, и это обычно что-то, что я только что вызвал.

Как только у вас есть pid, вы можете просто убить процесс. Это позволяет создавать простые скрипты для завершения процесса только в том случае, если он в данный момент выполняется.

в bash последний остановленный процесс (Ctrl-Z) вы убьете с помощью:

kill %%
kill -9 %%

или если хотите выбрать, используйте:

jobs

затем:

kill %N

например kill %2

Правильный способ – ввести jobs, затем использовать номер задания, чтобы убить его. Чтобы использовать pid для завершения, вам нужно вернуть его на передний план, как отмечено в первом ответе.

Попробуйте это

~/Desktop$ sleep 1000 &
[1] 7056

~/Desktop$ jobs

[1]+  Запущено  sleep 1000 &

/Desktop$ kill %1  #(%1 - это номер задания)

Если вы запустите jobs сразу после его завершения, вы должны увидеть это

Desktop$ jobs
[1]+  Завершено              sleep 1000

Самый простой способ – использовать флаг -9 на команде kill

user@host:/path> jobs
[1]+  Запущено                 /usr/home/script1.sh $i &
user@host:/path> fg
/usr/home/script1.sh $i
^C
[1]+  Остановлено                 /usr/home/script1.sh $i
user@host:/path> kill -9 %1
[1]+  Остановлено                 /usr/home/script1.sh $i
user@host:/path>
[1]+  Убит                  /usr/home/script1.sh $i
user@host:/path>
user@host:/path> jobs
user@host:/path>

Обычный пример — это инструмент stress. Допустим, вы выполнили следующее:

$ stress -c 4 -m 4 

и закрыли окно терминала. Процесс продолжит использовать ваши ресурсы в фоновом режиме.

Вот что я делаю:

$ x=`pgrep stress` ; sudo kill -9 $x 

pgrep отображает PID подлежащего процесса и сохраняет его в переменной x, которая затем используется командой kill -9 для завершения.

Перечислите все задачи, введя

jobs

Результат>>[1]+ Остановлено sudo nano ls.txt

Перенесите этот процесс на передний план и завершите

fg %1
затем нажмите ctrl+c

Я ленив и немного устал гуглить, какие инкантации ctrl % номер сигнала fg bg jobs disown и бог знает что еще использовать для чего-то, что должно быть тривиально.
Я рекомендую посмотреть альтернативы командной строки для обычно используемых команд в целом как способ повысить производительность, потому что для всего, что связано с запущенными процессами, я не могу достаточно рекомендовать btop. Я не скажу вам, как его использовать, потому что его на самом деле сделали для использования людьми.
Я почти уверен, что его можно найти через менеджер пакетов на ваш выбор, попробуйте, вы не пожалеете, также есть очень хороший procs.

Чтобы убить задание номер 1, вам нужно просто выполнить kill -9 `jobs -p 1` .
Чтобы убить все задания, не указывайте конкретный номер задания kill -9 `jobs -p` .

Конечно, чтобы перечислить задания, вы можете запустить jobs.

Ответ или решение

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

Метод 1: Использование команды ps

Вы можете использовать команду ps для поиска идентификатора процесса (PID) и последующего завершения процесса:

ps -eaf | grep [w]get

После этого найдите PID и выполните:

kill <PID>

Метод 2: Использование команды pgrep

Команда pgrep позволяет вам найти PID прямо по имени процесса:

pgrep wget

Затем завершите его:

kill <PID>

Метод 3: Использование команды pkill

Если вы уверены, что это единственный запущенный процесс wget, вы можете использовать pkill:

pkill wget

Метод 4: Использование команды jobs

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

jobs

После этого, чтобы завершить процесс, используйте команду kill с указанием номера задания:

kill %<номер_задания>

Метод 5: Использование команды fg

Вы также можете вернуть фоновый процесс в передний план, используя fg, а затем завершить его с помощью комбинации клавиш Ctrl+C:

fg %<номер_задания>

Уточнения

  • Если вы хотите завершить последний фоновый процесс, вы можете использовать команду kill $!, что завершит последний запущенный фоновый процесс.
  • Учтите, что использование kill отправляет сигнал по умолчанию (обычно SIGTERM, который мягко завершает процесс). Если процесс не реагирует, вы можете использовать более жесткий способ:
kill -9 <PID>

или

kill -9 %<номер_задания>

Заключение

Работа с фоновыми процессами и управление ими в GNU/Linux выполняется с помощью различных команд, которые позволяют пользователю гибко управлять запущенными задачами. Выберите подходящий способ в зависимости от вашей ситуации. Если у вас есть специфические требования, такие как длительная работа с загруженной system, рассмотрите возможность использования более продвинутых инструментов, например, htop или btop.

Оцените материал
Добавить комментарий

Капча загружается...