Perpipaan tidak mengharuskan instance pertama selesai sebelum yang lain dimulai. Sebenarnya, yang benar-benar dilakukannya adalah mengarahkan stdout dari instance pertama ke stdin yang kedua, sehingga mereka dapat berjalan secara simultan (seperti yang harus dilakukan agar bom fork berfungsi).
Nah, sebenarnya apa outputnya :
? apa yang diteruskan ke yang lain :
?
':' tidak menulis apa pun ke yang lain ':' instance, itu hanya mengarahkan stdout ke stdin dari instance kedua. Jika ia menulis sesuatu selama eksekusi (yang tidak akan pernah terjadi, karena ia tidak melakukan apa-apa selain forking sendiri) ia akan pergi ke stdin dari contoh lain.
Akan membantu membayangkan stdin dan stdout sebagai tumpukan:
Apa pun yang ditulis ke stdin akan ditumpuk siap ketika program memutuskan untuk membaca darinya, sementara stdout bekerja dengan cara yang sama: tumpukan Anda dapat menulis, sehingga program lain dapat membaca dari itu ketika mereka mau.
Dengan begitu mudah membayangkan situasi seperti pipa yang tidak memiliki komunikasi terjadi (dua tumpukan kosong) atau menulis dan membaca yang tidak disinkronkan.
Bagaimana tepatnya itu dieksekusi dua kali? Menurut pendapat saya, tidak ada yang diteruskan ke yang kedua :
sampai yang pertama :
selesai eksekusi, yang sebenarnya tidak akan pernah berakhir.
Karena kita hanya mengarahkan input dan output dari instance, tidak ada persyaratan untuk instance pertama selesai sebelum yang kedua dimulai. Sebenarnya biasanya diinginkan bahwa keduanya berjalan secara bersamaan sehingga yang kedua dapat bekerja dengan data yang diuraikan oleh yang pertama dengan cepat. Itulah yang terjadi di sini, keduanya akan dipanggil tanpa perlu menunggu yang pertama selesai. Itu berlaku untuk semua jalur rantai pipa perintah.
Saya berpikir bahwa logika yang sama berlaku untuk: () {: |: &} ;: dan
:(){ : & };:
Apakah pekerjaan yang sama dengan
:(){ :|: & };:
Yang pertama tidak akan berfungsi, karena meskipun berjalan sendiri secara rekursif, fungsinya dipanggil di latar belakang ( : &
). Yang pertama :
tidak menunggu sampai "anak" :
kembali sebelum mengakhiri sendiri, jadi pada akhirnya Anda mungkin hanya memiliki satu contoh :
berjalan. Jika Anda memilikinya :(){ : };:
akan berhasil, karena yang pertama :
akan menunggu "anak" :
untuk kembali, yang akan menunggu "anak" sendiri :
untuk kembali, dan seterusnya.
Berikut adalah bagaimana berbagai perintah akan terlihat dalam hal berapa banyak contoh akan berjalan:
:(){ : & };:
1 instance (panggilan :
dan berhenti) -> 1 instance (panggilan :
dan berhenti) -> 1 instance (panggilan :
dan berhenti) -> 1 instance -> ...
:(){ :|: &};:
1 instance (panggilan 2 :
dan berhenti) -> 2 instance (masing-masing panggilan 2 :
dan berhenti) -> 4 instance (masing-masing panggilan 2 :
dan berhenti) -> 8 instance -> ...
:(){ : };:
1 instance (memanggil :
dan menunggu untuk kembali) -> 2 instance (child memanggil yang lain :
dan menunggu untuk kembali) -> 3 instance (child memanggil yang lain :
dan menunggu sampai kembali) -> 4 instance -> ...
:(){ :|: };:
1 instance (memanggil 2 :
's dan menunggu mereka kembali) -> 3 instance (anak-anak memanggil 2 :
masing-masing dan menunggu mereka kembali) -> 7 instance (anak-anak memanggil :
masing-masing 2 dan menunggu mereka kembali) -> 15 instance -> ...
Seperti yang Anda lihat, memanggil fungsi di latar belakang (menggunakan &
) sebenarnya memperlambat bom fork, karena callee akan berhenti sebelum fungsi yang dipanggil kembali.
:|:
, yang kedua:
tidak perlu menunggu yang pertama selesai.