Не удается завершить процесс, который запущен, но, видимо, не виден в диспетчере задач

Я запустил приложение, которое не запускается, но не могу удалить его, потому что оно все еще работает. Я могу распечатать PID, но не убить процесс, используя его.

~ $ ps ax | grep snappr | awk '{print $1}'
70824
~ $ kill $(ps ax | grep snappr | awk '{print $1}')
-bash: kill: (70832) - No such process

2 ответа

Вы заметили, что у вас есть два разных PID в двух попытках?

Учтите это: если вы наберете команду вроде vi raven.txt, затем ps ax отобразит строку, которая показывает команду vi raven.txt, Аналогично, если вы наберете команду, как grep snappr, затем ps ax отобразит строку, которая показывает команду grep snappr, И, если вы трубите вывод этого ps через grep snappr, grep найдет строку, которая описывает себя. Итак, если вы введете

$ ps ax | grep snappr | awk '{print $1}'

несколько раз, он будет печатать разное число каждый раз (потому что он печатает PID grepи вы получите новый, уникальный grep обрабатывать каждый раз, когда вы запускаете команду).

Наконец, рассмотрим: kill Команда не может быть выполнена, пока ее аргументы не известны. Чтобы его аргумент был известен, $(ps ax | grep snappr | awk '{print $1}') трубопровод должен быть завершен. Это подразумевает, что grep должно быть прекращено1. Следовательно kill дается PID из grep процесс, но только после grep процесс завершен - поэтому, естественно, он сообщает "Нет такого процесса".

Возможно, я должен был упомянуть, что нет snappr процесс запущен. Если бы они были, ваша первая команда выдала бы два числа: PID snapprи PID grep snappr, Сейчас если snappr были запущены, ваша команда может начать работать полу-правильно, я имею в виду, что она делает то, что вы хотите, но также выдает сообщение об ошибке. Если snappr работает с PID 42097, и grep snappr работает с PID 70848, затем kill команда будет kill 42097 70858, который убьет snapprи получить сообщение об ошибке при попытке убить grep процесс, который больше не существует.

Возможно, вы захотите улучшить это. Мой любимый способ, который я придумал 20 лет назад, это изменить grep в grep "[s]nappr", который будет соответствовать snappr но не будет соответствовать самому себе. Другой подход заключается в использовании pgrep скорее, чем ps | grep,


1 В качестве альтернативы awk может закончиться, если grep просто закрыл свой стандартный вывод. Это было бы очень необычным поведением для *nix программы.

Краткий ответ

Не прыгайте через обруч Bash, чтобы убить snappr с ps по трубопроводу grep а затем по трубопроводу awk как это. Вместо этого попытайтесь убить это, используя это pkill; без суеты и суеты, и она нацелена на имя процесса из коробки:

sudo pkill snappr

Более длинный ответ

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

На самом деле я считаю, что метод, который вы используете, чтобы захватить идентификатор процесса (ps ax | grep snappr | awk '{print $1}') вернет полный список идентификаторов процессов, связанных с snappr независимо от того, родитель это или ребенок. Таким образом, используя это, вы можете уничтожить один идентификатор процесса, который является просто идентификатором дочернего процесса, но родительский идентификатор все еще будет активным и сможет "порождать" другой дочерний процесс для компенсации.

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

ps -p [process ID] -o ppid=

Выполнение этой простой команды в Bash даст вам идентификатор родительского процесса для идентификатора дочернего процесса, который вы вставили в [process ID], Так что, если идентификатор ребенка 4567 имеет идентификатор родительского процесса 123 тогда команда будет:

ps -p 4567 -o ppid=

И это вернется, 123,

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

Но все это говорит, почему бы не сделать вашу жизнь проще и просто бежать pkill как это:

sudo pkill snappr

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

Другие вопросы по тегам