như thế nào "trong khi (ngủ 100 &!) do; thực hiện" công việc trong zsh, và làm thế nào nó có thể được nhân rộng trong bash?


14

Theo Wikipedia, các forkbomb :(){ :|:& };: có thể bị ngăn chặn bằng lệnh zsh while (sleep 100 &!) do; done, mà sẽ được cho là spawn ngủ 100 quá trình cho đến khi . tất cả các quá trình forkbomb đã mất hết điều này có vẻ như kỳ diệu;?. như thế nào tôi đặc biệt tò mò như chính xác những gì "! &" có nghĩa là

gì sẽ một lệnh nhìn tương đương như trong bash

11

Lý do khiến bom ngã ba hoạt động là do có giới hạn hữu hạn về số lượng quy trình có thể chạy cùng một lúc và bom ngã ba được thiết kế để lấp đầy giới hạn này.

Vì mã ngã ba bạn cung cấp đã chết nếu nó không thể sinh ra một tiến trình con, các tiến trình cha mẹ không thực sự treo xung quanh, nhưng thực tế là trẻ tiếp tục tạo mới * -ildild giữ cho bảng xử lý đầy. Vì vậy, giải pháp ngủ được thiết kế để lẻn vào một số quy trình chỉ ngủ trong một thời gian ngắn, và đối với mỗi quá trình ngủ mà quản lý được tạo ra, có ít bom ngã ba xảy ra hơn. Cuối cùng, các quy trình ngủ sẽ tự lấp đầy bảng proces và các quả bom ngã ba chết đi.

Sau khi bảng xử lý đầy đủ các quy trình ngủ, vòng lặp while có thể bị hủy và các quá trình ngủ sẽ chết sau khi thời gian ngủ của chúng tăng lên. Sự cố được giải quyết.

Như đã được đề cập một phần quan trọng của lệnh zsh là run-in-nền &, vì vậy lệnh bash về cơ bản sẽ giống như được đưa ra trong câu trả lời khác:

while (sleep 100 &) do; done 

tôi don Không nghĩ rằng phần nohup/! là quan trọng trừ khi bạn muốn đăng xuất trong thời gian ngủ, nhưng tôi rất sẵn lòng được đặt thẳng nếu tôi sai.


2

? Câu hỏi rất thú vị!

Theo bài báo trên Wikipedia, mục đích của lệnh hoàn thành là tạo ra nhiều công việc vô hại sẽ vô hiệu hóa quả bom nĩa vì nó sẽ không thể sinh ra nhiều con hơn nữa.

Theo zsh manual,

Nếu một công việc được bắt đầu với &|' or &!', sau đó công việc được ngay lập tức từ bỏ. Sau khi khởi động, nó không có vị trí trong bảng công việc và không phải là tùy thuộc vào các tính năng kiểm soát công việc được mô tả ở đây.

Tôi không chắc chắn cách đạt được điều tương tự với bash. Tuy nhiên, giống như sau có thể làm:

nohup sleep 100 & 

8

Đầu bom ngã ba có thể được viết:

foo() 
{ 
    foo|foo& 
} 
foo 

Mà làm cho nó một chút rõ ràng hơn - mỗi lần lặp bắt đầu hai subprocesses, sau đó chết. Vì vậy, nếu forking thất bại, nó sẽ không treo xung quanh.

Do đó tất cả những gì chúng tôi phải làm là tạm thời ngừng hoạt động. Vì vậy, chúng tôi tạo ra các quy trình ngủ 100 và chiếm không gian quá trình, như các quy trình ngủ thực hiện.

zsh &! giống như & nhưng không xử lý quy trình mới (không giết nó lúc đăng xuất) - điều này có thể không quan trọng trong ví dụ này. (manual) Có thể thay thế bằng nohup.

Do đó bash:

while (nohup sleep 100 &) do; done 

nên làm việc.


6

Tôi là người đã viết một phần của bài viết trên Wikipedia (và người "khám phá" điều trị này sau khi vô tình bắt đầu quả bom ngã ba trên hệ thống của tôi!).

Lý do cho "&!" thay vì "&" thực sự ngăn chặn zsh thực hiện kiểm soát công việc trong quy trình mới, tức là, cố gắng quan tâm khi nào và nếu nó kết thúc. Tôi không nhớ chính xác lý do tại sao kiểm soát công việc là một vấn đề khi tôi thử nó, nhưng nó đã được. Bạn thực sự có thể thử nó để xem cách "chữa bệnh" hoạt động và những gì sẽ xảy ra nếu bạn không ngăn chặn kiểm soát công việc. Có lẽ vấn đề với kiểm soát công việc phải làm với một số lỗi trong zsh mà thậm chí không tồn tại trong bash, và có lẽ nó không còn liên quan trong zsh nữa.

Vì vậy, hãy thử chỉ một "&" với bash và nếu điều khiển công việc can thiệp, hãy thử tắt ("set + m") và hy vọng điều này sẽ hoạt động.

Bạn nói đúng rằng bài viết wikipedia có lẽ không nên phụ thuộc vào zsh.