Quả bom ngã ba này luôn nhắc nhở tôi về điều mà một giáo viên lập trình AI đã nói trong một trong những bài học đầu tiên tôi tham dự "Để hiểu đệ quy, trước tiên bạn phải hiểu đệ quy".
Tại cốt lõi của nó, quả bom này là một chức năng đệ quy . Về bản chất, bạn tạo một hàm, nó tự gọi nó, nó tự gọi nó, nó tự gọi nó .... cho đến khi tài nguyên hệ thống được tiêu thụ. Trong trường hợp cụ thể này, đệ quy được khuếch đại bằng cách sử dụng đường ống hàm cho chính nó và làm nền cho nó.
Tôi đã thấy điều này được trả lời trên StackOverflow và tôi nghĩ ví dụ đưa ra ở đó minh họa rõ nhất, chỉ vì dễ dàng nhìn thấy những gì nó làm trong nháy mắt (bị đánh cắp từ liên kết ở trên ...)
☃(){ ☃|☃& };☃
Xác định hàm lỗi ☃() { ... }
, phần thân gọi chính nó (hàm lỗi), dẫn đầu ra đến chính nó (hàm lỗi) ☃|☃
và làm nền cho kết quả &
. Sau đó, sau khi hàm được định nghĩa, thực sự gọi hàm bug , ; ☃
.
Tôi lưu ý rằng ít nhất trên Arch VM của tôi, nhu cầu làm nền cho quá trình không phải là một yêu cầu để có cùng kết quả cuối cùng, để tiêu thụ tất cả không gian quy trình có sẵn và khiến cho máy chủ lưu trữ b0rked. Trên thực tế bây giờ tôi đã nói rằng dường như đôi khi chấm dứt quá trình chạy trốn và sau khi sàng lọc -bash: fork: Resource temporarily unavailable
nó sẽ dừng lại với một Terminated
(và journalctl
hiển thị việc bán phá giá lõi bash).
Để trả lời câu hỏi của bạn về csh / tcsh, cả hai hàm này đều không hỗ trợ các hàm, bạn chỉ có thể đặt bí danh. Vì vậy, đối với các shell đó, bạn phải viết một kịch bản shell mà gọi chính nó theo cách đệ quy.
zsh dường như chịu chung số phận (với cùng một mã), không đổ lõi và khiến Arch đưa ra Out of memory: Kill process 216 (zsh) score 0 or sacrifice child.
, nhưng nó vẫn tiếp tục rẽ nhánh. Sau một thời gian, nó sẽ phát biểu Killed process 162 (systemd-logind) ...
(và vẫn tiếp tục có một zsh forking).
Arch dường như không có pacman
phiên bản của ksh, vì vậy tôi đã phải thử nó trên debian. ksh đối tượng :
như là một tên hàm, nhưng sử dụng một cái gì đó - nói b()
thay vào đó dường như có kết quả mong muốn.