Вбийте всі фонові завдання


63

Чи є більш компактна форма вбивства фонових завдань, ніж:

for i in {1..5}; do kill %$i; done

Крім того, {1..5} очевидно, що в ньому є жорстко закодоване магічне число, як я можу зробити його "N", коли N є правильним числом, не роблячи:

$(jobs | wc -l)

Я фактично використовую \ j в PS1, щоб отримати # керованих робочих місць, це еквівалент?


3
kill $(jobs -p)здається легше.
jw013

Я вважаю за краще вбивати роботу індивідуально, якщо це можливо. (Я, можливо, неправильно зрозумів ваш коментар)
Robottinosino

for pid in $(jobs -p); do kill $pid; done?
jw013

3
@ jw013 Це не тільки простіше, це фактично правильно (будь ласка, опублікуйте це як відповідь), на відміну від рішення, заснованого на підрахунку рядків, вихід jobsяких працює, лише якщо завдання трапляються нумерованими послідовно. О, і "вбивати завдання окремо" безглуздо: передача декількох PID в killкоманду робить точно те саме, що передавати їх окремо.
Жиль

Я вводив команду неправильно, вбиваю $ (jobs -p) слова, і мені здається дуже коректним. Готовий прийняти.
Robottinosino

Відповіді:


102

Щоб просто killвсе фонові завдання , керовані bash, зробити

kill $(jobs -p)

Зауважте, що оскільки обидва jobsі killвбудовані в них bash, ви не повинні надто довго стикатися з помилками списку аргументів .


2
Також для нащадків те, що бахамат вважає способом зробити це, zshдискваліфікує їх як будь-які повноваження з цієї теми.
peth

Я відчуваю, що я повинен це знати, але як '$' працює тут?
fersarr

1
@fersarr Here you go
jw013

@bahamat Це насправді не працює, оскільки PID може знаходитись у полі 2 або 3 залежно від того, чи є одна з% + або% - чи ні. Що працює kill %${(k)^jobdirs}, що дійсно довше; якщо вам потрібно перелічити PID, ви можете використовувати ще довше ${${jobstates#*:*:}%%=*}.
Жиль

На CentOS моє підказка чекає додаткового введення>
Janac Meena

15

Використовуйте xargsзамість $(jobs -p)підкоманди, бо якщо jobs -pпорожня, то команда kill не зможе.

jobs -p | xargs kill

1
Це має той самий точний ефект, але він друкує довідку та завершує роботу з кодом 123
кішка

1
Команда прекрасно працює на OSX, але не працює на Debian
brunocascio

Це чудово працює на CentOS 6
Janac Meena

jobs -p | xargs -rn10 killбуде краще, якщо jobs -pне поверне PID. Зауважте, що цей -rваріант - розширення GNU.
NarūnasK

Як було сказано вище, -rце короткий формат --no-run-if-emptyрозширення GNU, до xargsякого вказується не виконувати команду, якщо у stdin немає даних.
Ентоні Г - справедливість для Моніки

3

Я вважаю за краще перевірити, чи існують якісь завдання, перш ніж їх вбити - таким чином сценарій не вийде з ладу, якщо нічого не працює.

Це також коротше набрати. Киньте це у вашому .bash_profile:

function killjobs () {
    JOBS="$(jobs -p)";
    if [ -n "${JOBS}" ]; then;
        kill -KILL ${JOBS};
    fi
}

Потім запустіть:

killjobs

Вбивати будь-які запущені роботи.


1

У мене є кілька фонових складених команд, які я хочу граціозно припинити, надсилаючи SIGINT до кожного процесу в macOS. Жодне з інших рішень для цього не працювало належним чином, тому я придумав це:

jobs -p | xargs -n1 pkill -SIGINT -g

jobs -p перелічує фонові процеси, розпочаті поточною оболонкою.

xargs -n1 виконує pkill один раз для кожного завдання.

pkill -SIGINT -g посилає SIGINT (те саме, що ctrl + c) на всі процеси в групі процесів.


1

Я думаю, що залежно від того, що jobs -pдає результат, рішення може бути дещо іншим. У моєму випадку

$ jobs -p
[1]  - 96029 running    some job
[2]  + 96111 running    some other job

Тому робити наступне - не корисно.

$ jobs -p | xargs kill
kill: illegal process id: [1]

З іншого боку, біг kill $(jobs -p)працює, але тягне за собою безліч повідомлень про помилки, оскільки також передаються рядки, що не належать до PID kill.

Тому моє рішення grepспершу PID, а потім використовувати xargsнаступним чином:

$ jobs -p | grep -o -E '\s\d+\s' | xargs kill

1
Яку оболонку ви використовуєте? Що echo $0показує? Що help jobsпоказує? Проілюстрований вихід не сумісний з POSIX ; будь-яка реалізація jobsповинна мати -pваріант із задуманою поведінкою.
Wildcard

1
Дякуємо, що вказали на це. Я використовую zsh, і це є причиною дивного виходу. Я перейшов на bash і jobs -pзробив лише вихід PID. Щойно я дізнався, що zsh не є повністю сумісним з POSIX.
Fanchen Bao

0

Здається, jobs -p | xargs killце виконує роботу, проте вона створює деякий небажаний вихід, який можна вбити. Тут я групую результат jobs -p, маючи / не маючи + або - символу

function killjobs() {
    JOBS=$(jobs -p)
    echo $JOBS | grep -v "+\|-"| awk '{print $2}' | xargs kill -9
    echo $JOBS | grep "+\|-"| awk '{print $3}' | xargs kill -9
}

А пізніше можна просто зателефонувати killjobs

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.