Bash:當 control-c 無法殺死進程時該怎麼辦,因為 bash 腳本包含一個呼叫另一個進程的循環:對於開/關電源按鈕是否有更好的解決方案?

Bash:當 control-c 無法殺死進程時該怎麼辦,因為 bash 腳本包含一個呼叫另一個進程的循環:對於開/關電源按鈕是否有更好的解決方案?

這個問題的完整標題是:

Bash:當 control-c 無法殺死進程時該怎麼辦,因為 bash 腳本包含一個呼叫另一個進程的循環:對於開/關電源按鈕是否有更好的解決方案?

這個問題的標題是相當不言自明的,但這裡有一些更詳細的資訊:

我正在運行一個 bash 腳本,它調用另一個程式。 (運行/執行另一個程式。)

該程序是數據/曲線擬合程序,不能用 中斷CTRL-C。但是,從讀到這篇文章郵政,我發現我可以殺死它CTRL-\

假設性想法...

所以可以直接敲擊鍵盤,按住 CTRL 鍵,然後敲擊按鍵\如果你昨天買了一個非常昂貴的機械鍵盤,但沒有足夠的錢去購買另一個你願意「混搭」的便宜鍵盤,該怎麼辦(因為你不想用完這 10^6 個按鍵中的任何一個)在你閃亮的新機械鍵盤磨損之前擁有),或者沒有足夠的時間在你的房子裡找到你的舊鍵盤,因為你的房子要么極為混亂(一團糟)或因為同時發生諸如晶片盤火災之類的緊急情況...

還要考慮到一個循環正在調用這個擬合程序,也許您正在擬合 1000 個數據文件,按該\鍵 1000 次可能會花費很長時間。

超空間思維...

甚至;如果您在 bash 腳本中犯了一個錯誤並且它實際上正在執行無限循環怎麼辦?

在這種情況下,您可以採取什麼措施來停止父腳本的執行?您可以拔掉電腦的插頭,按住電源按鈕 10 秒鐘將其關閉,或者將其扔進晶片盤火中以停止其工作,但由於可能會發生資料遺失,這些解決方案似乎不明智。

理論上,我們可以運行系統監視器,也許還可以退出bash 進程,但是如果您有許多同名的此類進程,這可能很難找到...此外,您可能有一台單核計算機,或者一台具有 N 個核心的多核心計算機,運行 N 個進程,這些進程都試圖使用 100% CPU。或者也許只有 1 個進程使用的內存超過了您擁有的 4 GB 內存,因此您的計算機速度非常慢……至少目前無法運行系統監視器。此後的下一個最佳選擇是按 CTRL-ALT-F1 並嘗試以 root 身份登入並使用ps -Athen找到有問題的 bash 父級kill PID...但是,如果您的電腦負載如此之重,這可能會花費您幾分鐘的時間它正在不斷地寫入以進行交換。

SIG TERM exec cpu_broken.sh;重新召集;清晰的螢幕;清晰的思考過程;繼續...

有更好的解決方案嗎?

答案1

因此,基本上,您運行的腳本使所有內容都無法訪問,並且您需要快速且簡單的解決方案來阻止它。重新啟動電源的另一種方法是按住SYSRQ鍵(在許多情況下與 鍵相同PRTSC),然後一一按下R, E, I, S, U, B。基本上,這是終止所有正在運行的進程並重新啟動系統的安全方法。

替代方法是sudo nano /proc/sysrq-trigger在該文件中寫入 b , 並保存。系統將立即重新啟動

更多資訊: https://en.wikipedia.org/wiki/Magic_SysRq_key

答案2

您需要殺死整個進程組。進程組 ID (PGID) 是啟動該群組的進程的 PID。要終止進程組,您需要找到啟動該進程組的進程的 PID,即啟動該進程組的腳本或命令。語法是:

kill -- -PGID

例如:

kill -- -1234

這裡1234是PGID(進程組ID)。

這會將 SIGTERM 傳送到進程組中的所有進程。若要傳送不同的訊號,例如 SIGKILL (9),請執行以下操作:

kill -9 -1234

如何查找 PGID:

你可以做:

ps -eo 'pid,ppid,pgid,cmd'

這將顯示 PID、PPID(父進程 ID)、PGID 和進程名稱。

現在您可以使用grep或任何其他合適的方法找到PGID,然後透過上述方法殺死它。

我使用命令來顯示 PPID 的原因是因為您也可以嘗試透過以下方式終止基於 PPID 匹配的進程pkill

pkill -P PPID

例如:

pkill -P 6789

使用這種方法,您需要找到所有父進程(和子進程),然後殺死它們,所以在我看來,如果您想殺死所有進程樹,則殺死整個進程樹是更好的方法。

答案3

通常您可以使用top,htop或類似的命令來查找進程並殺死它(或者如果您知道進程的名稱或 PID,則可以killallpkill)。例如,使用top,我可以選擇從終端運行的腳本並按k+終止它Enter

在此輸入影像描述

如果這不起作用,k++9應該Enter使用 SIGKILL 訊號。 SIGKILL 請求立即終止進程,而不是像 SIGTERM 那樣等待進程完成清理資源等操作。Ctrl+C進程僅發送 SIGINT 來中斷進程,就像 SIGTERM 一樣。

使用 htop 中的樹狀視圖(按t)也表示您可以確定腳本的父進程,並終止它們以確保它不會繼續循環。

也可以看看:

相關內容