Làm thế nào 'rm -rf /' có thể xóa tất cả các tệp trong hệ thống?


81

Tôi chưa thử lệnh này trên Ubuntu (vì lý do rõ ràng) vì vậy tôi không chắc liệu Ubuntu có cho phép thực thi hay không. Nhưng nó nổi tiếng vì đã xóa mọi thứ. Vì tò mò, điều gì xảy ra khi kernel và /binbị xóa? Làm thế nào để rmduy trì một ngăn xếp thời gian chạy? Làm thế nào để rmquản lý để giao tiếp với hệ thống tập tin và xóa hoàn toàn? Làm thế nào để nó giao tiếp với phần cứng?


18
rm -rf /không xóa bất cứ thứ gì mà không có --no-preserve-root.
muru

47
Trải nghiệm đầu tiên của tôi với Linux là tạo ra Ubuntu vm để tôi có thể "rm -rf /" nó. Tôi khuyên bạn nên thử điều này. Cài đặt khá nhanh, nó giữ cho máy chủ của bạn an toàn và rất thú vị khi xem các phần khác nhau của HĐH bị vỡ trước mắt bạn. Rất thỏa mãn.
DJMcMayhem

22
Nhắc nhở tôi về báo cáo lỗi được yêu thích của tôi: bugzilla.redhat.com/show_orms.cgi?id=1202858 "Kết quả mong đợi: Mực được khởi động lại. Kết quả thực tế: Tất cả các tệp đều bị xóa trên máy."

9
Bạn nên đọc Unix Recovery Legend . Miễn là bạn vẫn đăng nhập vào hệ vỏ, hệ thống sẽ không hoàn toàn chết!
200_success

2
@gerrit Tôi đã làm . :)
muru

Câu trả lời:


79

Nó không quan trọng mà /bin/rmbị xóa. Nó chỉ được chạy một lần và đến thời điểm đó, tất cả được tải trong bộ nhớ, như mọi thứ khác được yêu cầu để tiếp tục gửi xóa vào hệ thống tệp và đĩa.


Thanh bên / Cập nhật: Mỗi câu trả lời của David Hoelzer (và được đề cập trong các bình luận), inode liên kết cứng /bin/rmđược sử dụng để chỉ đúng cho đến khi rmkết thúc (vì Linux giữ ở trạng thái mở) nhưng thực tế đó không liên quan; trạng thái của đĩa hoàn toàn không thành vấn đề.

Nhị phân được tải vào bộ nhớ trước khi chạy. Ngay cả khi bạn có thể hủy rmdữ liệu đĩa theo cách thủ công , nó sẽ không ảnh hưởng hoặc ngăn việc xóa hoàn thành (giả sử bạn không làm cho đĩa không khả dụng).

Không có ý tưởng gì một inode hoặc hardlink là gì? Đây là câu trả lời mà tôi đã làm việc đó.


Dù sao, đây cũng là lý do tại sao bạn có thể xóa gói cho kernel hiện tại mà không cần máy tính nổ. Miễn là bạn cài đặt một phiên bản khác, nó sẽ có thể khởi động.

Một lần nữa, điều này hoạt động vì rmchỉ được gọi một lần. Sau đây sẽ thất bại sau khi /bin/rmchết vì nó gọi nó một lần cho mỗi tên tệp:

find / -exec rm {} \;

Điều đó nói rằng, find / -exec rm -rf {} +find / -print0 | xargs -0 rm -rfcả hai cũng có khả năng thất bại vì cả hai đều có giới hạn đối số, có nghĩa là họ sẽ chỉ xóa một số tệp trước khi được gọi lại. Tại một số điểm trên hành trình, /bin/rmcó thể hết hạn ( được phát hành) trước khi các tệp còn lại bị xóa. Nó không được đảm bảo mặc dù. Nếu /bin/là thư mục cuối cùng được nhập, các phương thức này có thể hoạt động.


7
Như @DavidHoelzer giải thích, các tệp không được liên kết không cần phải có trong bộ nhớ để tiếp tục hoạt động. Nhân biết rằng có một xử lý tệp mở, vì vậy nó giữ dữ liệu tệp xung quanh để đáp ứng mọi yêu cầu (bao gồm cả trang) cho đến khi xử lý cuối cùng được đóng lại.
Andrew Medico

4
@Desty, không, điều đó sẽ không thành công, miễn /bin/rmlà không đủ gần để kết thúc ở đợt cuối cùng; -exec ... {} +(thoát dấu gạch chéo ngược là không cần thiết) vẫn dẫn đến nhiều lần thực thi; không phải một cho mỗi tệp, mà là một cho mỗi lô dựa trên số lượng đối số có thể phù hợp với ARG_MAX.
Charles Duffy

6
@Oli, nó không phải là về phân trang; bộ đếm tham chiếu được liên kết với inode, không phải mục nhập thư mục và một tệp xử lý tệp mở được tính là một tham chiếu (giống như một liên kết cứng), ngăn chặn inode bị hủy. Kích thước tệp hoàn toàn không phải là một yếu tố và điều này xảy ra ngay cả khi không có không gian hoán đổi (do đó, không có phân trang).
Charles Duffy

2
@CharlesDuffy Bất kể bạn có dung lượng trao đổi hay không, phân trang sẽ được sử dụng cho tất cả các tệp ánh xạ bộ nhớ. Điều đó bao gồm tất cả các thực thi và thư viện. Trong thực tế thiếu không gian hoán đổi thực sự có thể có nghĩa là nhiều phân trang đang diễn ra cho các tệp ánh xạ bộ nhớ.
kasperd

2
@CharlesDuffy Có, kích thước thực sự không liên quan. Bộ nhớ ánh xạ tệp không gây ra bất kỳ nội dung nào của tệp được tải cho đến khi truy cập. Và bộ nhớ được sử dụng để tải các phần được truy cập của tệp có thể được giải phóng lại nếu cần, sau đó nó sẽ được tải từ tệp nếu được truy cập lại. Vì vậy, tệp thực sự phải ở trên hệ thống tệp miễn là nó được ánh xạ và điều này hoạt động theo cách tương tự đối với một tệp một trang như đối với một tệp đủ lớn để bao trùm toàn bộ không gian địa chỉ. (Các chi tiết phức tạp hơn một chút đối với ánh xạ sao chép cần ghi cho liên kết động.)
kasperd

57

Tôi chưa thử lệnh này trên Ubuntu (vì lý do rõ ràng) vì vậy tôi không chắc liệu Ubuntu có cho phép thực thi hay không.

Tôi đã làm. rm -rf / --no-preserve-rootđã chạy trong một phiên root được mở trực tiếp trên máy, trong khi tôi cũng được kết nối sshtừ một máy khác, sử dụng tài khoản root.

Điều gì xảy ra là bạn bắt đầu nhận được rất nhiều tin nhắn như:

rm: không thể xóa '/ ...': Thao tác không được phép

hoặc là:

rm: không thể xóa '/ ...': Thiết bị hoặc tài nguyên bận

nhập mô tả hình ảnh ở đây

Đáng ngạc nhiên, sshkết nối vẫn mở cho đến khi kết thúc hoạt động. Chỉ khi tôi đóng kết nối và cố gắng mở lại thì mới xuất hiện lỗi:

Đọc từ ổ cắm không thành công: Thiết lập lại kết nối bằng ngang hàng

Trên máy, bốn thư mục vẫn còn:

  • /dev. Đây là nơi lưu trữ các tập tin thiết bị.
  • /procHệ thống tập tin bộ nhớ trong bộ nhớ được tạo bởi kernel.
  • /run, một vị trí hệ thống tập tin tiêu chuẩn cho daemon.
  • /sys. Điều này cho phép bạn có được thông tin về hệ thống và các thành phần của nó.

Điều này có nghĩa là không còn nhiều, và không có nhiều để làm ở đó. Bạn không thể ls(mặc dù khi sử dụng Tab, tên của các thư mục và tệp vẫn được hiển thị). Bạn có thể cdtrong các thư mục khác nhau, và cả các echocông cụ, nhưng các lệnh như catkhông còn khả dụng nữa.

Không có sudomột trong hai.

shutdown -h nowvà cũng rebootbiến mất, vì vậy tùy chọn duy nhất của bạn dường như tắt máy bằng tay. Đăng xuất ( exit) không hoạt động, ngay cả khi nó hiển thị văn bản "đăng xuất" đẹp.

Khi bạn cố gắng khởi động lại máy, bạn sẽ gặp lỗi GRUB 15, và sau đó, không có gì xảy ra, tại thời điểm đó bạn có thể bắt đầu nghĩ rằng bạn rmcó thể đã làm điều gì đó không tốt cho hệ thống của mình.

nhập mô tả hình ảnh ở đây

Bạn cũng có thể làm được

Không, chờ đã, đừng làm điều đó trên máy của bạn!

Thay vào đó, những gì bạn có thể làm là chạy một máy ảo . Máy ảo có một lợi ích là làm cho thử nghiệm thực sự dễ dàng. Vì bạn đang sử dụng Ubuntu, bạn có thể quan tâm đến vmbuilder . Đây là một công cụ cho phép bạn triển khai các máy ảo trong vài phút (tài liệu chính thức tuyên bố rằng nó có thể được thực hiện "trong khoảng một phút", nhưng thời gian thực tế, ngay cả trên phần cứng nhanh, chỉ khoảng hai ba phút .

Khi việc triển khai kết thúc, bạn có một môi trường mà bạn có thể chơi. Nếu bạn kết thúc việc phá hủy nó, điều đó không thành vấn đề: bạn triển khai lại máy và hai phút sau bạn có thể tiếp tục.

Nếu bạn sử dụng phần mềm như VMWare, bạn cũng có thể quan tâm đến ảnh chụp nhanh (lưu ý rằng Trình phát VMWare miễn phí không có tính năng này; bạn phải mua VMware Workstation). Lưu ý rằng Hyper-V miễn phí và hỗ trợ ảnh chụp nhanh (nhưng bạn phải chạy Windows).

Lợi ích của ảnh chụp nhanh là bạn có thể mất một phần trong vài phần nghìn giây. Quay trở lại một ảnh chụp nhanh mất nhiều thời gian hơn, nhưng thường chỉ là vài giây. Điều này làm cho thử nghiệm thậm chí dễ dàng hơn và nhanh hơn.

Thử nghiệm này không giới hạn ở chính hệ điều hành. Bạn có thể làm tất cả mọi thứ liên quan đến phần mềm. Có một ứng dụng đáng ngờ? Hãy kiểm tra nó trong máy ảo VM nếu nó là virus, nó sẽ không gây hại gì. Bạn muốn kiểm tra một hoạt động trên cơ sở dữ liệu, cho rằng nó có thể ảnh hưởng đến môi trường? Kiểm tra nó trong một VM.

Điều gì nếu bạn đã làm điều đó trên một máy thực tế, không thử nghiệm?

Những điều tồi tệ xảy ra. Lưu ý rằng rmbảo vệ bạn khỏi chính bạn: rm -rf /sẽ không hoạt động: bạn cần sử dụng --no-preserve-root. Tuy nhiên, điều gì sẽ xảy ra nếu bạn thực sự đạt được, do nhầm lẫn, để loại bỏ mọi thứ?

rmchỉ hủy liên kết các tệp , nhưng dữ liệu vẫn còn đó, trên đĩa cứng của bạn. Điều này giúp bạn có thể khôi phục nó sau này (đó là lý do tại sao bạn không nên vứt bỏ đĩa cứng của mình với dữ liệu nhạy cảm khi chúng không còn hoạt động nữa).

Điều này có nghĩa là bạn chỉ cần có một PC dự phòng có vỏ ổ cứng để thực sự phục hồi gần như tất cả các tệp. Điều quan trọng là tránh ghi bất cứ thứ gì vào đĩa cứng để khôi phục: dữ liệu bạn viết sẽ ghi đè lên các tệp không được liên kết.

Theo ghi nhận của bài viết trong bình luận của 200_success , nếu bạn hành động thông minh, bạn có thể lấy lại máy ngay cả khi không có PC dự phòng. Nếu bạn chỉ quan tâm đến dữ liệu, tôi sẽ không bận tâm đến việc phục hồi dữ liệu bằng PC dự phòng dễ dàng hơn nhiều.


VirtualBox hỗ trợ ảnh chụp nhanh đĩa.
Nathan Osman

1
Lưu ý rằng vi-rút thường được thiết kế để phát hiện máy ảo, vì vậy tôi sẽ không tư vấn cho quá trình phát hiện vi-rút này. Một câu hỏi nhỏ: bốn thư mục còn lại không phải là thư mục "thực", phải không? Họ không thực sự trên ổ cứng? Những gì còn lại trên ổ cứng sau khi chạy lệnh này?
raptortech97

2
@ raptortech97 rmkhông thực sự xóa nội dung khỏi ổ cứng, nó chỉ "hủy liên kết" (tách rời) dữ liệu thực tế trên đĩa khỏi cây hệ thống tập tin, đánh dấu nó miễn phí (để cuối cùng có thể bị ghi đè thông qua việc sử dụng máy tính thông thường). Vì vậy, nếu bạn, nói, rm -rf ~không phải tất cả bị mất, miễn là bạn hành động nhanh chóng (ví dụ với extundelete). Bạn có thể nghĩ về nó như một phiên bản thậm chí không đáng tin cậy hơn của thư mục "đã xóa" trong hộp thư của bạn, bạn có thể lấy lại nội dung nếu bạn không chờ đợi quá lâu, nhưng cuối cùng nó sẽ bị xóa.
Thomas

@ raptortech97 Mặt khác, nếu vì lý do nào đó bạn không sử dụng rmnhưng shred, trò chơi đã kết thúc khá nhiều, mặc dù bạn có thể có thời gian để nhận ra sai lầm của mình và hủy bỏ vì việc băm nhỏ mất nhiều thời gian hơn.
Thomas

5
Các thư mục đang được lưu giữ rất có thể là điểm gắn kết của một số hình thức hoặc khác. Và các lệnh tiếp tục hoạt động là các lệnh dựng sẵn bash, không phải các tệp nhị phân riêng biệt. Vì vậy, trong khi lsđã mất, for i in /*; do echo $i; donenên làm việc. Và để thay thế catbạn có thể sử dụng một lệnh như thế nào while read i; do echo $i; done < /proc/self/maps.
MvG

25

Lý do là lớp đặt tên tệp (những gì bạn thấy ls) thực sự chỉ để thuận tiện cho bạn. Trình điều khiển hệ thống tập tin và kernel chỉ quan tâm đến inode là gì. Khi một tệp được tham chiếu theo tên, nó sẽ ngay lập tức được dịch sang inode chứa tất cả siêu dữ liệu bao gồm các quyền, các khối dữ liệu trên đĩa, ID chủ sở hữu, ID nhóm và số lượng liên kết.

Số lượng liên kết là những gì thực sự quan trọng ở đây. Khi bạn xóa một tệp trên hệ thống UNIX, cuộc gọi hệ thống thực tế là một unlink. Điều xảy ra dưới mui xe là số lượng liên kết (số lượng tên tệp trong lớp đặt tên tệp) chỉ vào nút đó bị giảm. Hệ thống tệp biết rằng một tệp sẽ bị xóa khi số lượng liên kết bằng không.

Khi một tệp bị xóa bởi rmnó cũng sẽ chỉnh sửa tệp thư mục (vâng, đó chỉ là một tệp chứa tên tệp và nút in cùng với một vài bit khác không quan trọng đối với câu trả lời này). Tuy nhiên, chính việc hủy liên kết thực sự giải phóng tài nguyên đĩa.

Điều này dẫn đến một số hiệu ứng thú vị khác. Đầu tiên, có thể mở tệp có số lượng liên kết bằng không. Điều này xảy ra khi rm -rf /xóa mục nhập cho /bin/rm. Tệp đang mở (có một tệp xử lý tệp) nhưng nút được đánh dấu bị xóa (liên kết đếm = 0). Tài nguyên đĩa sẽ không được phát hành và sử dụng lại cho đến khi đóng tập tin.

Một hiệu ứng thú vị khác là những gì xảy ra khi bạn có một nút có số liên kết lớn hơn 0 nhưng không có gì trong lớp đặt tên tệp trỏ đến nó. Theo một nghĩa nào đó, đây là một tập tin ẩn rất tốt :). Để có quyền truy cập vào nó, bạn sẽ phải sử dụng một mức độ thấp để tham chiếu nó theo số inode chứ không phải theo tên (vì không có) hoặc chỉnh sửa một mục nhập thư mục để trỏ vào inode bằng trình soạn thảo hex.

Hiệu ứng thú vị thứ ba là những gì sẽ xảy ra nếu bạn giảm số lượng liên kết xuống 0 nhưng chỉ ra một mục nhập thư mục ở nút inode. Tôi sẽ để điều đó cho bạn thử nghiệm nếu bạn muốn. Tuy nhiên, rõ ràng, cả hai cuối cùng đều dẫn đến hệ thống tập tin ở trạng thái không nhất quán.


Nhìn theo một cách khác, số lượng liên kết không bằng 0, vì mở tệp sẽ thêm một liên kết trong / Proc.
OrangeDog

@OrangeDog, hành vi này vẫn tồn tại ngay cả khi Procfs không được đếm.
Charles Duffy

1
@OrangeDog Charles Duffy là chính xác. Các tập tin xử lý trong / Proc không sửa đổi các nút, điều chỉnh số lượng liên kết.
David Hoelzer

/ Proc và / sys là sự phản ánh của trạng thái hệ thống (kernel) hiện tại. Chỉ chọn hành động cho các tệp và thư mục trong đó thực sự thay đổi trạng thái hệ thống.
một CVn

18

Câu trả lời trước là tốt, nhưng tôi muốn làm rõ một chi tiết:

rmkhông chỉ là một lệnh. Đây là một chương trình được tìm thấy trong PATH.

Do đó, những gì xảy ra khi bạn thực hiện là như sau:

  • bạn gọi (như root) rm -rf /
  • phiên bản của chương trình rmđược tải trong bộ nhớ với các đối số -rf/
  • dựa trên các đối số này, chương trình rmbắt đầu các hoạt động của nó (trải qua mọi thứ trong mount / phân vùng và loại bỏ đệ quy các tham chiếu đến nó [xin lỗi về tính kỹ thuật;)])
  • một khi nó kết thúc, thể hiện của rmchương trình được tải
  • tại thời điểm này, những thứ duy nhất trong bộ nhớ là các chương trình đã được tải ở đó trước đó (ví dụ: bash nếu bạn có thiết bị đầu cuối mở trong Ubuntu, môi trường máy tính để bàn, kernel, trình điều khiển, v.v.)
  • nếu bạn cố gắng gọi bất kỳ lệnh nào khác (trong trường hợp Linux biến nó thành một chương trình độc lập), nó sẽ thất bại vì không tìm thấy chương trình nào như vậy ở các vị trí PATH (và các vị trí PATH không còn tồn tại nữa). Tuy nhiên mọi thứ một khi đã tải vẫn sẽ chạy

Để hiểu cách hoạt động của nó, hãy thử cài đặt LAMP trên ubfox (trong Virtualbox), một số bộ đệm opcode script và PHP, sau đó gọi lệnh ác này. Đáng ngạc nhiên (nếu bạn đủ may mắn và bộ đệm opcode của bạn sẽ không nhận thấy việc xóa tệp php), bạn vẫn có thể truy cập các tập lệnh php từ bên ngoài thông qua máy chủ web apache!

PS: lệnh độc ác này thậm chí chạy dưới dạng root sẽ không xóa everything, nó không thể xóa một số tiến trình đặc quyền kernel /procvà không thể xóa một số nội dung khỏi /devcác thiết bị xuất hiện trên hệ thống của bạn dưới dạng tệp. Trong thực tế, root không phải là toàn năng như chúng ta nghĩ, hạt nhân mặt khác là.

PPS: Cũng như một ý nghĩ thứ hai, bạn cũng sẽ vẫn có các tệp lockedtheo quy trình khác tại thời điểm xóa.


Trên Linux, bạn chắc chắn có thể loại bỏ các nút thiết bị khi chạy bằng root. Nhưng có, bạn không thể xóa bất cứ thứ gì /procvì đây là hệ thống tệp chỉ đọc. Tương tự như vậy cho /sys. Tôi tin rằng bạn cũng không thể xóa điểm gắn kết.
Brian

@AlexKey Tôi đề nghị chỉnh sửa để làm rõ ý của bạn bằng "lệnh nhúng không phải kernel" (hoặc để tránh cụm từ đó hoàn toàn). Có vẻ như bạn đang nói rằng có những lệnh bạn có thể chạy qua trình bao được triển khai trực tiếp trong kernel để chúng luôn hoạt động bất kể là gì. (Đó là, như bạn có thể biết nhưng nhiều người đọc có thể không, không phải vậy: khi bạn chạy một lệnh như thế cd, điều này gọi shell được dựng bởi tên đó - lệnh đó được tích hợp vào shell chứ không phải kernel.) Bạn có nghĩa là "lệnh" Alt + SysRq?
Eliah Kagan

@Brian có phụ thuộc vào distro không? Tôi đã làm việc trong nhiều bản phát hành và thật buồn cười là nó đã mắc lỗi này nhiều lần. Như tôi nhớ lại sau khi kiểm tra hài cốt của / vẫn còn một cái gì đó trong / dev, nhưng nó có thể là những thứ như cdrom hoặc đĩa mềm ...
Alexey Kamenskiy

@EliahKagan Khi tôi cố gắng giữ distro độc lập, vì vậy tôi đã sử dụng thuật ngữ này. Nó có nghĩa là không phải trên tất cả các hệ thống lệnh cli có nghĩa là chương trình bên ngoài. Nhưng cảm ơn, vì đã chỉ ra rằng, tôi sẽ làm rõ quan điểm.
Alexey Kamenskiy

@AlexKey Tôi tin rằng bạn sẽ không thể xóa /dev/ptsvì đây là điểm gắn kết. (Và cả hệ thống tệp chỉ đọc nữa.)
Brian

1

Khi mọi thứ đã bị xóa khỏi ổ cứng, kernel vẫn hoạt động nhưng bị kẹt vì không còn thiết bị và chương trình, lệnh, v.v.

HĐH sẽ không hoạt động nữa.

Và đúng như những gì Oli nói, lệnh được tải / thực thi vào bộ nhớ và sẽ không có gì ngăn chặn được trừ khi bạn giết tiến trình này (tất nhiên, nếu lệnh kill vẫn còn tồn tại ^^).


4
Tại sao kernel bị kẹt? Câu trả lời của MainMa gợi ý khác và hỗ trợ những gì tôi đã mong đợi.
MvG

4
Các chương trình chạy từ bộ nhớ, không phải ổ cứng. Nhân sẽ không biết có gì sai cho đến khi khởi động lại.
phyrfox

Có lẽ tôi cần thay đổi các từ tôi đã sử dụng, kernel ít nhiều bị "kẹt" khi không có thiết bị, chương trình, v.v. và nếu bạn không ở trước bảng điều khiển gốc, bạn không thể làm điều xấu, thậm chí là không biết điều khiển bạn không thể làm những thứ xấu. Nhưng tôi sẽ thay đổi từ ngữ trong câu trả lời của tôi vì nó sai lệch, tôi đồng ý.
s1mmel

0

Xin lưu ý rằng nếu hệ thống có selinux và selinux ở chế độ thực thi và các chính sách của selinux được thiết lập đúng; sau đó sẽ không có gì nhiều xảy ra

Selinux là kiểm soát truy cập bắt buộc, có nghĩa là, trong số nhiều thứ, người dùng root thực sự không có nhiều sức mạnh để phá hủy hệ thống hơn bất kỳ người dùng nào khác trên hệ thống.

Selinux được thi hành trong kernel; bạn sẽ phải thỏa hiệp hạt nhân để có được xung quanh nó.

Trên một hệ thống được thiết kế tốt với các chính sách Selinux tốt, root sẽ không thể làm được gì nhiều trên hệ thống.

Các phiên bản sau của Android có Selinux thi hành chỉ vì lý do này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.