Linux: убить фоновое задание


195

Как убить последнюю порожденную фоновую задачу в linux?

Пример:

doSomething
doAnotherThing
doB &
doC
doD
#kill doB
????

18
Как это может быть не связано с программированием? Bash программирование не программирование?
flybywire

6
Это в области перекрытия между SO и SU, но я думаю, что здесь лучше подходит для SO. Мой критерий для такого подхода заключается в том, что если @flybywire делает это в скрипте, то это программирование. Если бы он просто хотел сделать это из командной строки, я бы сказал, что он принадлежит SU.
Билл Ящерица

10
Сценарии оболочки тоже программирование.
Клет

Ответы:


234

Для этого в bash есть специальная переменная:

kill $!

$! расширяется до PID последнего процесса, выполняемого в фоновом режиме.


68
@ polm23; нет, ^Zне фоновые задания, это их останавливает. Последующее bgвыполняет фактическое «фоновое изображение» (возобновляет выполнение в фоновом режиме), и после этого $!работает как ожидалось.
Фальстро

Предполагая, что ????одна или несколько команд выполняются после уничтожения, если любая из этих команд полагается на работу, выполняемую фоновым процессом, помните о любых задачах очистки или завершения, которые фоновый процесс может выполнить в обработчике сигнала после получение (trappable) сигнала. Лучше всего добавить wait(возможно, после syncили даже sleep <n>) прямо перед первой из таких «зависимых» команд.
извед

2
Для завершения: Поскольку одиночный% также относится к текущему заданию, вы можете уничтожить остановленное задание (^ z) с помощью «kill%». Я использую это почти всегда после ^ z.
t3o

Это работает, только если у вас включен контроль заданий, который включен только по умолчанию в интерактивных оболочках (хотя, поскольку вы имеете в виду использование ctrl-z, я полагаю, вы также имеете в виду использование интерактивной оболочки) - но это было изложенные в других ответах здесь, не уверен, почему это "для полноты" :)
Falstro

289

Вы можете убить по номеру работы. Когда вы поставите задачу в фоновом режиме, вы увидите что-то вроде:

$ ./script &
[1] 35341

Это [1]номер задания, на который можно ссылаться следующим образом:

$ kill %1
$ kill %%  # Most recent background job

Чтобы увидеть список рабочих номеров, используйте jobsкоманду. Больше от man bash:

Существует несколько способов ссылки на задание в оболочке. Персонаж %вводит имя работы. Номер задания nможет упоминаться как %n. Задание также может упоминаться с использованием префикса имени, использованного для его запуска, или с использованием подстроки, которая появляется в его командной строке. Например, %ceотносится к остановленной ceработе. Если префикс соответствует более чем одному заданию, bash сообщает об ошибке. Использование %?ce, с другой стороны, относится к любому заданию, содержащему строку ceв его командной строке. Если подстрока соответствует более чем одному заданию, bash сообщает об ошибке. Символы %%и%+обратитесь к понятию оболочки текущего задания, которое является последним заданием, остановленным, когда оно находилось на переднем плане или началось в фоновом режиме. На предыдущую работу можно ссылаться с помощью %-. В выводе, относящемся к заданиям (например, выводе команды jobs), текущее задание всегда помечается знаком a +, а предыдущее задание - -. Сингл %(без сопровождающей спецификации работы) также относится к текущей работе.


Для записи, я думаю, что это работает, только если управление заданиями включено. Хотя я думаю, что вы можете включить его в scripts ( set -m), он предназначен для интерактивного использования. См stackoverflow.com/questions/690266/... , а также
falstro

9
Очень полезные символы, эти %1и %%- особенно. Некоторые вещи не умирают на Ctrl-C, поэтому вам нужно Ctrl-Z их, а затем kill -9 %%. Один пример, где я нашел это полезным: while true; do mplayer <some unstable online radio>; date >> restarts.log; done- Ctrl-C просто приведет вас к следующей итерации цикла. Прежде чем я должен был сделать psили, может быть jobs -l, а затем повторно введите PID, что утомительно.
Томаш Гандор

Есть ли один для всех рабочих мест?
CMCDragonkai

3
@TomaszGandor Вот почему вы можете заменить while trueнаwhile sleep 1 . Это даст вам небольшую задержку перед перезапуском, если вы сможете жить с этим, и если вы дважды нажмете ctrl-c, второй прервет сон, завершив его ненулевым выходом и выходом из цикла.
Фальстро

45

Следующая команда дает вам список всех фоновых процессов в вашем сеансе вместе с pid. Затем вы можете использовать его, чтобы убить процесс.

jobs -l

Пример использования:

$ sleep 300 &
$ jobs -l
[1]+ 31139 Running                 sleep 300 &
$ kill 31139

25

Это должно убить все фоновые процессы:

jobs -p | xargs kill -9

1
Это то, что я использовал бы раньше, но kill -9 %%меньше печатать :)
Томаш Гандор

4
@TomaszGandor Это убьет только текущее задание, т.е. последнее задание было остановлено на переднем плане или запущено на заднем плане. Команда в ответе убьет ВСЕ задания.
bitek


2
skill doB

skill версия команды kill, которая позволяет вам выбрать один или несколько процессов на основе заданных критериев.



0

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

Как и в ответе @John Kugelman,% относится к спецификации работы. как эффективно это найти? используйте команду less & & pattern , кажется, что man использует меньше пейджер (не уверен), в man bash введите &%, затем введите Enter, чтобы отобразить только строки, содержащие '%', для повторного показа всего введите &. затем введите.


-3

Просто используйте команду killall:

killall имя задачи

для получения дополнительной информации и дополнительных параметров введите «man killall».


4
Я думаю, что killall немного агрессивен, когда у вас есть легкий доступ к PID. И опасно тоже, особенно если ты root
Дейв Фогт

3
Не очень полезно, если нужно, killall pythonили killall java, когда что-то полезное работает в системе.
Томаш Гандор
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.