無法終止任務管理器中正在運行但顯然不可見的進程

無法終止任務管理器中正在運行但顯然不可見的進程

我啟動了一個無法運行的應用程序,但無法刪除它,因為它仍在運行。我可以列印 PID,但不能殺死使用它的進程。

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

答案1

您是否注意到兩次嘗試中獲得了兩個不同的 PID?

考慮一下:如果您鍵入類似 的命令vi raven.txtps ax則會顯示一行顯示 的命令vi raven.txt。同樣,如果您鍵入類似 的命令grep snapprps ax則會顯示一行顯示 的命令grep snappr。並且,如果您ps透過管道輸出該輸出grep snapprgrep則會找到該行那是在描述自己。所以,如果你輸入

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

重複地,它每次都會列印不同的數字(因為它會列印 的 PID ,並且每次執行命令時grep都會得到一個新的、唯一的進程)。grep

最後,請考慮:kill在知道其參數之前,無法執行該命令。要了解其參數,$(ps ax | grep snappr | awk '{print $1}')管道必須已完成。這意味著1grep必須已終止。因此,只有在該進程終止後才會給出該進程的 PID——因此,它自然會報告「沒有這樣的進程」。killgrepgrep

也許我應該提到沒有snappr進程正在運行。如果有,您的第一個指令將輸出兩個數字: 的 PIDsnappr和 的 PID grep snappr。現在,如果snappr正在運行,您的命令可能會開始半正確地運行,我的意思是它會執行您想要的操作,但也會給出錯誤訊息。如果snappr以 PID 42097 運行,並grep snappr以 PID 70848 運行,則kill命令將為kill 42097 70858,這將殺死snappr 並在嘗試終止grep不再存在的進程時收到錯誤訊息。

您可能想要改進這一點。我最喜歡的方法是我 20 年前發明的,它將更改為grepgrep "[s]nappr"它會匹配snappr但不會匹配自身。另一種方法是使用pgrep而不是ps | grep.


1或者,awk如果grep僅關閉其標準輸出,則可以完成。對於 *nix 程式來說,這是非常不尋常的行為。

答案2

簡短的答案

不要跳過 Bash 的圈子來用snapprps管道通過grep然後通過awk這樣的管道來殺死。相反,嘗試使用這樣的方式殺死它pkill;沒有混亂或大驚小怪,它的目標是基於開箱即用的進程名稱:

sudo pkill snappr

更長的答案

不太清楚如何鯛魚在系統進程層級上運行,但問題可能是您僅取得子進程 ID 而不是父進程 ID。

事實上,我相信您用來獲取進程 ID 的方法 ( ps ax | grep snappr | awk '{print $1}') 將返回所連接的進程 ID 的完整列表,snappr無論它是父進程還是子進程。所以用你可能殺死一個只是子進程 ID 的進程 ID,但父 ID 仍然處於活動狀態,並且能夠「產生」另一個子進程來進行補償。

因此,也許您可以執行類似的操作來獲取您提供的任何進程 ID 的最終父 ID,並對其執行操作;其工作原理的簡單概念證明:

ps -p [process ID] -o ppid=

在 Bash 中執行該裸命令將為您提供您輸入的子進程 ID 的父進程 ID [process ID]。因此,如果子 ID4567有一個父進程 ID,123那麼命令將是:

ps -p 4567 -o ppid=

那將會返回,123

也就是說,這可能是處理雜散進程的一種危險方法,因為如果您的腳本獲取 的實際父進程 ID snapper,那麼該進程 ID 的父進程實際上可能是您自己的 Bash shell。因此,您可能會無意中殺死您的 Bash shell,而不是讓snapper您離開系統,同時讓snapper進程保持運作。

但話雖如此,為什麼不讓你的生活變得更輕鬆,直接跑步呢pkill像這樣:

sudo pkill snappr

這將殺死所有連接到的進程,而snappr無需任何花哨的命令列操作。

相關內容