Не удается завершить процесс, который запущен, но, видимо, не виден в диспетчере задач
Я запустил приложение, которое не запускается, но не могу удалить его, потому что оно все еще работает. Я могу распечатать 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
без каких-либо модных жонглирование командной строки.