假設我有一個愚蠢的腳本:
while true;do
touch ~/test_file
sleep 3
done
然后我將腳本啟動到后臺并離開終端:
chmod u x silly_script.sh
./silly_script.sh &
exit
我現在有辦法識別并停止該腳本嗎?我看到它的方式是,每個命令都是在它自己的行程中啟動的,我可能能夠捕獲并殺死一個命令,比如“睡眠 3”,但不能執行整個腳本,我弄錯了嗎?我預計會出現一個帶有腳本名稱的行程,但事實并非如此。如果我用“source silly_script.sh”啟動腳本,我找不到名為“source”的行程。我是否需要識別正在執行腳本的 bash 實體?我該怎么做?
編輯:有一些創造性的解決方案,但到目前為止,它們需要立即存盤腳本執行的 PID,或者不留下 bash 會話^D或exit. 我理解,應該避免這種運行腳本的方式,但我很難相信,任何低權限用戶都可以,即使是偶然的,在后臺啟動一個煩人的腳本,例如用垃圾填充驅動器檔案或重復啟動某些軟體的新實體,甚至管理員也別無選擇,只能重新啟動服務器,因為一個簡單的腳本可以隱藏它的識別符號,甚至無需嘗試。
uj5u.com熱心網友回復:
在這里的優秀人員的幫助下,我能夠得出我需要的答案:
確實,腳本在它自己的行程中運行每個命令,所以例如殺死sleep 3命令不會對正在運行的腳本做任何事情,但是通過像這樣的命令,sleep 3您可以通過查找父行程來找到運行腳本的 bash 實體:因此,在完成上述操作后,您可以運行ps axf以樹形式顯示所有行程。然后你會發現這個部分:
18660 ? S 0:00 /bin/bash
18696 ? S 0:00 \_ sleep 3
現在你已經找到了 bash 實體,它正在運行腳本并且可以停止它:(kill 18660
當然你的 PID 和我的不一樣)
uj5u.com熱心網友回復:
該jobs命令將顯示所有正在運行的后臺作業。您可以使用 kill 通過 id 殺死后臺作業,例如:
$ sleep 9999 &
[1] 58730
$ jobs
[1] Running sleep 9999 &
$ kill %1
[1] Terminated sleep 9999
$ jobs
$
58730是后臺任務的PID,1是它的任務ID。在這種情況下kill 58730, kill %1` 將具有相同的效果。
有關詳細資訊,請參閱JOB CONTROL部分man bash。
當您退出時,后臺作業將收到一個終止信號并死亡(假設它是這樣處理信號的 - 在您的簡單示例中是這樣),除非您disown先執行它。
該殺死將傳播到該sleep行程,該行程很可能會忽略它并繼續睡眠。如果是這種情況,您仍然會在ps -e輸出中看到它,但父 pid 為 1 表示其原始父不再存在。
您可以使用它ps -o ppid= <pid>來查找流程的父級,或pstree -ap可視化作業層次結構并直觀地查找父級。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/441519.html
