Уничтожьте много экземпляров рабочего процесса с одной командой

Я попытаюсь объяснить, как работают переменные оболочки. Абсолютно возможно добавить локальные переменные к переменной среды как ПУТЬ.

Каждый рабочий процесс имеет список переменных среды. Они - name=value пары. Когда новый процесс создается с ветвлением (), это наследовало те переменные (среди прочего как открытые файлы, идентификатор пользователя, и т.д.). В контрастной оболочке переменные являются внутренним понятием оболочки. Они не наследованы при создании нового процесса. Можно экспортировать переменные оболочки и сделать их переменными среды. Когда в сценарии оболочки Вы пишете FOO='bar' это - переменная оболочки. Можно попытаться создать 2 сценария:

# test1.sh
FOO='bar'
sh test2.sh

# test2.sh
echo "${FOO}"

При выполнении первого сценария, он устанавливает внутреннюю переменную оболочки, затем называет ветвление (). Родительский процесс оболочки будет ожидать (), чтобы ребенок закончил затем, выполнение продолжается (если существует больше команд). В должностном лице дочернего процесса () назван для загрузки новой оболочки. Этот новый процесс не знает о НЕЧТО. Если Вы изменяете первый сценарий:

# test1.sh
export FOO='bar'
sh test2.sh

переменная НЕЧТО становится частью среды и наследованный к разветвленному процессу. Важно отметить, что среда не глобальна. Дочерние процессы не могут влиять на переменные среды своего родителя.

# test3.sh
sh test4.sh
echo "${PATH}"

# test4.sh
export PATH="${PATH}:/new/path"

Модификации в test4.sh не видимы в test3.sh. Информация просто не идет тем путем. Когда дочерний процесс заканчивается, его среда отбрасывается. Давайте изменим test3.sh:

# test3.sh
source test4.sh
echo "${PATH}"

Источник является встроенной командой оболочки. Это говорит оболочке открывать файл затем чтение и выполнять его содержание. Существует только единственный процесс оболочки. Таким образом, вызывающая сторона видит модификации к переменным среды и даже окружает переменные.

Поскольку Вы, вероятно, знаете, что ПУТЬ является специальной переменной среды, которая говорит оболочку, где искать другие исполняемые файлы. Когда новая оболочка входа в систему запускается это автоматически источники .bash_profile. Переменные, объявленные там, будут видимы. Однако в .bash_profile при вызове других сценариев с sh ПУТЕМ, Вы устанавливаете в тех сценариях, будет потерян.

78
15.11.2016, 05:31
12 ответов

Что случилось со старым добрым,

for pid in $(ps -ef | grep "some search" | awk '{print $2}'); do kill -9 $pid; done

Существуют способы сделать это более эффективным,

for pid in $(ps -ef | awk '/some search/ {print $2}'); do kill -9 $pid; done

и другие изменения, но на базовом уровне, это всегда работало на меня.

103
27.01.2020, 19:31
  • 1
    Проголосовавший, знал только о первом изменении. Вторые более эффективные взгляды, спасибо. –  The Dark Knight 11.10.2012, 18:38
  • 2
    @TheDarkKnight, которым проблема с этим методом состоит в том, что Вы часто заканчиваете тем, что уничтожили больше, чем Вы, предназначил. При записи надежного “некоторый поиск” хитер. В соответствии с Linux, используйте pkill, который обрабатывает большую часть тонкости. –  Gilles 'SO- stop being evil' 12.10.2012, 01:55
  • 3
    , я не уверен, что это настолько хитро, если Вы после определенного двоичного файла это может быть довольно надежно. Я всегда выполняю его как echo kill -9 $pid сначала так или иначе, таким образом, я знаю то, что я получаю. Я не уверен, что AIX имеет pkill, который является моим хлебом с маслом UNIX. И это достаточно действительно плохо, чтобы вниз проголосоваться - нечетный. –  EightBitTony 12.10.2012, 10:08
  • 4
    Если не абсолютно необходимо, необходимо отправить процессу SIGTERM вместо SIGKILL. –   29.06.2013, 19:25
  • 5
    я должен добавить, что эти 2 метода не будут работать во всех оболочках, например, это не продолжит работать csh –  non sequitor 25.02.2016, 17:55

Используйте killall,

killall vi

Это уничтожит всю команду, названную 'vi'

Вы могли бы также добавить сигнал также, например, SIGKILL

killall -9 vi

39
27.01.2020, 19:31
  • 1
    Правильно, можно также добавить сигнал, как который Вы хотите, killall -9 vi –  Hola Soy Edu Feliz Navidad 11.10.2012, 10:19
  • 2
    я не думаю killall, является naswer к нему: Уничтожение файлом только работает на исполняемые файлы, которые сохранены открытыми во время выполнения, т.е. нечистые исполняемые файлы не могут быть уничтожены этот путь. Ввод killall имя не может иметь желаемого эффекта на системы не-Linux, особенно при выполнении привилегированным пользователем. Что, если я пытаюсь удалить много экземпляров некоторого процесса не-Linux? killall-w не обнаруживает, если процесс исчезает и заменяется новым процессом с тем же PID между сканированиями. Если процессы меняют свое имя, killall не может соответствовать им правильно. положительная сторона –  The Dark Knight 11.10.2012, 10:26
  • 3
    Знайте, что это только работает над Linux и BSD. На Солярисе и некоторых других системах killall делает точно, что имя предлагает..., что оно уничтожает init-процесс. –  Bobby 11.10.2012, 12:20
  • 4
    На AIX это "отменяет все процессы, которые Вы запустили, кроме тех, которые производят процесс killall". –  EightBitTony 12.10.2012, 12:54

pkill то, что я рекомендую, если это доступно (Linux, FreeBSD, NetBSD, OpenBSD, Солярис). Можно указать процессы названием команды полной командной строкой или другими критериями. Например, pkill vi закрывает все программы, название команды которых содержит подстроку vi. Уничтожить только названные процессы vi, использовать pkill -x vi. Уничтожить только названные процессы vi с последним аргументом, заканчивающимся в .conf, использовать pkill -fx 'vi.*\.conf'.

Видеть список PIDs это pkill отправил бы сигнал в, использовать pgrep, который имеет точно тот же синтаксис за исключением того, что он не принимает имя сигнала или число. Для наблюдения большей информации об этих процессах работать

ps -p "$(pgrep …)"

В соответствии с Linux, Вам нужно ps -p $(pgrep -d, …) вместо этого (это - ошибка: Linux ps не совместимо POSIX).

Другим распространенным способом определить процессы для уничтожения являются процессы, которые имеют определенный открытый файл (который может быть исполняемым файлом процесса). Можно перечислить их с fuser; использовать fuser -k отправить им сигнал. Например, fuser -k /usr/bin/find уничтожает все рабочие экземпляры find.

Если существует безудержный процесс, который продолжает разветвляться, Вы, возможно, должны уничтожить целую группу процесса сразу. Группа процесса определяется отрицанием ее лидера, который является процессом предка всех процессов в группе. Видеть группу процесса, что процесс принадлежит, выполненный ps -o pgid (плюс любая опция выбрать, который процесс (процессы) отобразиться). Если Вы решаете, что хотите уничтожить лидера группы процесса 1234 и все его дети, работать kill -1234 или kill -HUP -1234 или любой другой сигнал.

Если Вы не можете найти лучший путь, использовать ps с надлежащими опциями перечислить все процессы и отфильтровать его с grep или некоторая другая текстовая команда фильтрации. Заботьтесь для не случайного соответствия другим процессам, которые, оказывается, выполняют команду с аналогичным именем, или с аргументом, который содержит то имя. Например:

kill $(ps -o pid -o comm | awk '$2 == "vi" {print $1}')

Помните что Ваш grep или awk сама команда может быть перечислена в ps вывод (ps и команда фильтрации запускается параллельно, поэтому обнаружится ли она или не зависит от синхронизации). Это особенно важно, если аргументы команды включены в ps вывод.

31
27.01.2020, 19:31
  • 1
    Большое спасибо это является действительно потрясающим. То, что Вы дали, является своего рода учебным руководством. Еще раз спасибо. Проголосовавший –  The Dark Knight 15.10.2012, 09:20

pkill очень хорошо здесь. Можно дать ему много параметров для совершенствования шаблона.

6
27.01.2020, 19:31
  • 1
    Не доступный на всем UNIXes и никаком упоминании об определенном UNIX или подобной UNIX ОС в вопросе. –  EightBitTony 12.10.2012, 12:50
  • 2
    @EightBitTony pkill доступно на Linux, BSD и Солярисе - afaik. Таким образом, это имеет большее распространение, чем killall. –  Nils 12.10.2012, 14:12
  • 3
    , который я согласовываю, но killall еще более проблематичен, потому что существует несколько инструментов с тем же именем, которые имеют существенно другое поведение, которым это казалось бы. Мне не нравятся ответы killall также. pkill не существует на AIX или HP-UX и несмотря на то, чему некоторым людям нравится верить, существует все еще значительное, базирующееся не-Linux UNIX в мире. –  EightBitTony 12.10.2012, 15:21
  • 4
    @EightBitTony именно поэтому Ваш ответ является принятым. Но я не использовал бы его на Солярисе (который является Unix, также). –  Nils 12.10.2012, 22:18

Я предложил бы, чтобы Вы попробовали pkill.

Исключая: ps -ef | pkill -f command

Показать список всех процессов, которые будут уничтожены первая попытка к pgrep:

Исключая: ps -ef | pgrep -f command

0
27.01.2020, 19:31
  • 1
    , Что цель передать по каналу является выводом ps -ef в pkill или pgrep? Эти команды не читают из входа стандарта. –  Kusalananda♦ 25.01.2017, 14:43
$ ps -eaf  | grep "xyz" | grep -v grep | awk 'print $2' | xargs kill
-2
27.01.2020, 19:31

pgrep "name-of-application" | xargs kill -9

Это было достаточно просто, чтобы запомнить и работало хорошо для меня.

-1
27.01.2020, 19:31

Интересно, никто об этом не упомянул. pidof выводит через пробел pid процессов, соответствующих переданному имени процесса. Таким образом, вы можете напрямую использовать его вывод с помощью kill без конвейерной обработки. В Arch Linux я использую

kill -9 $ (pidof )

Обратной стороной этого решения является то, что оно не позволяет использовать регулярные выражения.

3
27.01.2020, 19:31

Самый простой способ сделать - это сначала проверить, правильно ли вы получаете процесс Идентификаторы с:

pgrep -f [part_of_a_command]

Если результат соответствует ожиданиям. Используйте:

pkill -f [part_of_a_command]
6
27.01.2020, 19:31
ps -ef | pgrep -f "search" | xargs kill -9  
-2
27.01.2020, 19:31

Вы можете завершить несколько разных процессов с помощью приведенной ниже команды

pkill -9 -f "\.\/.+\s\.|process1|process2|process3\[^"

Обратите внимание, что это приведет к уничтожению процесса, соответствующего приведенному выше шаблону, что означает, чтоprocess1abcprocess2defprocess3ghiтакже будет уничтожен.

1
27.01.2020, 19:31

напишите это и назовите killer.sh :)бесконечный цикл и процесс уничтожения

#!/bin/bash
while :
do
    echo "Press [CTRL+C] to stop.."
    for pid in $(ps -ef | awk '/your process name/ {print $2}'); do kill -9 $pid; done  
    # credit to above answer 
    sleep 1
done
-1
30.01.2021, 02:31

Теги

Похожие вопросы