Bit terakhir dari kode, ;:
menjalankan fungsinya :(){ ... }
. Di sinilah garpu terjadi.
Titik koma mengakhiri perintah pertama, dan kita mulai yang lain, yaitu memanggil fungsi :
. Definisi fungsi ini mencakup panggilan untuk dirinya sendiri ( :
) dan output dari panggilan ini disalurkan ke versi latar belakang :
. Ini menopang proses tanpa batas.
Setiap kali Anda memanggil fungsi :()
Anda memanggil fungsi C fork()
. Akhirnya ini akan menghabiskan semua ID proses (PID) pada sistem.
Contoh
Anda dapat bertukar |:&
dengan sesuatu yang lain sehingga Anda dapat mengetahui apa yang sedang terjadi.
Siapkan pengamat
Dalam satu jendela terminal lakukan ini:
$ watch "ps -eaf|grep \"[s]leep 61\""
Siapkan bom garpu "fuse delay"
Di jendela lain kita akan menjalankan versi bom fork yang sedikit dimodifikasi. Versi ini akan berusaha mencekik dirinya sendiri sehingga kita dapat mempelajari apa yang dilakukannya. Versi kami akan tidur selama 61 detik sebelum memanggil fungsi :()
.
Kami juga akan melatarbelakangi panggilan awal, setelah dipanggil. Ctrl+ z, lalu ketikkan bg
.
$ :(){ sleep 61; : | : & };:
# control + z
[1]+ Stopped sleep 61
[2] 5845
$ bg
[1]+ sleep 61 &
Sekarang jika kita menjalankan jobs
perintah di jendela awal kita akan melihat ini:
$ jobs
[1]- Running sleep 61 &
[2]+ Running : | : &
Setelah beberapa menit:
$ jobs
[1]- Done sleep 61
[2]+ Done : | :
Periksa dengan pengamat
Sementara itu di jendela lain tempat kami menjalankan watch
:
Every 2.0s: ps -eaf|grep "[s]leep 61" Sat Aug 31 12:48:14 2013
saml 6112 6108 0 12:47 pts/2 00:00:00 sleep 61
saml 6115 6110 0 12:47 pts/2 00:00:00 sleep 61
saml 6116 6111 0 12:47 pts/2 00:00:00 sleep 61
saml 6117 6109 0 12:47 pts/2 00:00:00 sleep 61
saml 6119 6114 0 12:47 pts/2 00:00:00 sleep 61
saml 6120 6113 0 12:47 pts/2 00:00:00 sleep 61
saml 6122 6118 0 12:47 pts/2 00:00:00 sleep 61
saml 6123 6121 0 12:47 pts/2 00:00:00 sleep 61
Hierarki proses
Dan a ps -auxf
menunjukkan hierarki proses ini:
$ ps -auxf
saml 6245 0.0 0.0 115184 5316 pts/2 S 12:48 0:00 bash
saml 6247 0.0 0.0 100988 468 pts/2 S 12:48 0:00 \_ sleep 61
....
....
saml 6250 0.0 0.0 115184 5328 pts/2 S 12:48 0:00 bash
saml 6268 0.0 0.0 100988 468 pts/2 S 12:48 0:00 \_ sleep 61
saml 6251 0.0 0.0 115184 5320 pts/2 S 12:48 0:00 bash
saml 6272 0.0 0.0 100988 468 pts/2 S 12:48 0:00 \_ sleep 61
saml 6252 0.0 0.0 115184 5324 pts/2 S 12:48 0:00 bash
saml 6269 0.0 0.0 100988 464 pts/2 S 12:48 0:00 \_ sleep 61
...
...
Bersihkan waktu
A killall bash
akan menghentikan sesuatu sebelum mereka lepas kendali. Melakukan pembersihan dengan cara ini mungkin sedikit berat, cara yang lebih lembut yang tidak berpotensi merobohkan setiap bash
shell, adalah dengan melakukan hal berikut:
Tentukan terminal pseudo mana yang akan dijalankan oleh bom fork
$ tty
/dev/pts/4
Bunuh terminal semu
$ pkill -t pts/4
Jadi apa yang terjadi?
Yah setiap doa bash
dan sleep
adalah panggilan ke fungsi C fork()
dari bash
shell dari mana perintah itu dijalankan.