:() { :|:& }; : # <-- 打開終端,輸入這個,回車.你看到了什麼??

代碼:
:() { :|:& }; :


爲什麼這個東西會讓你的系統死掉???有人執行了然後問我 
讓我們來分析一下這段代碼,我改一下格式,但內容是一樣的 代碼:
:() # 定義一個叫“:”的過程 
{ # 標記過程內容的開始 
: | : & # 執行“:”這個過程,然後通過管道接到“:”再執行一次,而且每一次執行,都會在後臺執行 
}; # 標記過程內容的結束,因爲是同一行來寫,所以要加上“;”,這樣才能接後面的內容 
: # 執行:


兩個原因使它死掉: 
1. 無限遞歸。倘若只是簡單的: &,那麼每次遞歸調用的時候一邊在後臺執行,而另外一邊則在退出。然而,即使如此,倘若你只是下面的內容,你仍然可以看到不少bash,而且是不斷地增多。其原因很可能是一邊產生新的進程的同時,另外一邊的進程卻還沒完全退出。然而,這種產生方式,終究會在某個時刻達到動態平衡,也就是新產生新進程的速度和結束進程的速度達到平衡。因而,這並不一定會讓系統掛掉。 代碼:
show_ps() { ps -A | grep bash; show_ps & }; show_ps


2. 平衡的破壞 
2.1 兩個進程同時開始 
使用管道的時候,不是一個進程完了然後另外一個進程纔開始,而是兩個進程同時開始,其中一個進程讀取另外一個進程的標準輸出作爲標準輸入。 代碼:
tee | grep abc


可以看到,這個時候,我們只有輸入滿足正則表達式abc的內容,它纔會被重複。而這個過程會一直持續到我們結束tee的輸入。 

2.2 死機的原因:同時執行導致平衡的破壞。(注意:這只是一個簡化的模型。同時執行只是理想情況,真正在執行的時候,會由於實際情況有所偏差,但由於偏差並不大,所以這個模型仍然可用;另外,現在假設每個“:”都會產生一個進程,然而實際情況是這樣的:先: | : &產生一個進程,接着由於兩次:的調用進而產生兩個進程,再接着: | : &所在的進程消亡,如此循環,顯然,實際情況只是比這個模型增加了一些自我抵銷的中間環節而已) 
在: | : &執行的時候,我們知道,兩個“:”是同時執行的。倘若同時有n個“:”在運行,那麼,它將首先產生2*n個進程,然後這n個進程再結束掉,此時相當於新增加了2*n個進程。那從第一次調用開始,假設進程產生後馬上結束,那麼進程數量的變化將呈2^n的趨勢變化。然而產生新進程的速度是極快的,因而在極短的時間內將會產生無數的進程。在這種情況下,死機是很正常的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章