Từ khi nào POSIX và GNU rm không xóa /?


23

Trong vài năm nay, rmtiện ích GNU sẽ không xóa /trừ khi nó được gọi với --no-preserve-roottùy chọn. Tuy nhiên, mệnh lệnh rm -rf /đã được lưu giữ trong tiềm thức tập thể là nguy hiểm trong một thời gian rất dài và mọi người vẫn thường coi đó là một mệnh lệnh "đáng sợ".

Tôi đã tự hỏi khi quy tắc này rmkhông thể xóa /lần đầu tiên xuất hiện. Tôi đã kiểm tra thông số kỹ thuật POSIX và tôi có thể thấy rằng trong khi POSIX: 2008 bao gồm tính năng an toàn này, POSIX: 2001 thì không. Do các phiên bản trực tuyến của thông số kỹ thuật POSIX được cập nhật theo thời gian, với mỗi lần phát hành phụ mới, tôi cũng đã kiểm tra máy quay lại và tìm thấy trang có liên quan của POSIX: 2008 từ năm 2010 và có thể xác nhận rằng quy tắc rmkhông thể xóa /đã được liệt kê rồi.

Vì vậy, câu hỏi của tôi là:

  • Khi nào quy tắc rmkhông thể xóa /được thêm vào thông số kỹ thuật POSIX? Có phải trong phiên bản 2008 gốc của Thông số kỹ thuật UNIX đơn phiên bản 4 hoặc đã được thêm vào trong bản sửa đổi?
  • Khi nào giới hạn này được thêm vào GNU rm? Tôi khá chắc chắn rằng đó là trước khi nó được thêm vào POSIX, nhưng khi nào thì nó xảy ra?


1
Liên quan: Giải thích nhóm Austin # 019 (2003), trong đó mô tả (nhưng không thực hiện) thay đổi.
Michael Homer

Câu trả lời:


28

Bạn có thể tìm thấy phiên bản HTML của tất cả các phiên bản POSIX 2008 trực tuyến:

Điều đó đã được thêm vào trong phiên bản 2008.

Chương trình kỹ thuật nói chung không thêm các tính năng mới.

Bạn có thể thấy phiên bản trước ( http://pub.opengroup.org/onlinepub/009695399/utilities/rm.html ) (POSIX 2004) không có văn bản đó.

Văn bản mới đã được chấp nhận trong hội nghị nhóm austin 2003-05-09 để đưa vào sửa đổi sau này của tiêu chuẩn.

Nó được yêu cầu bởi John Beck của Sun microsystems vào tháng 3 cùng năm (liên kết yêu cầu đăng ký opengroup, xem thêm Yêu cầu nâng cao số 5 tại đây ).

John Beck đã viết, vào ngày 11 tháng 3 năm 2003:

@ page 820 line 31681-31683 section rm comment {JTB-1}

Problem:

Defect code :  3. Clarification required

An occasional user mistake, with devastating consequences, is to
write a shell script with a line such as:
      rm -rf $VARIABLE1/$VARIABLE2
or
      rm -rf /$VARIABLE1
without verifying that either variable is set, which can lead to
      rm -rf /
being the resulting command.  Since there is no plausible
circumstance under which this is the desired behavior, it seems
reasonable to disallow this.  Such a safeguard would, however,
violate the current specification.

Action:

Either extend the exceptions for . and .. on the noted lines
to list / as well, or specify that the behavior of rm if an
operand resolves to / is undefined.

GNU rmđã thêm --preserve-root--no-preserve-rootcác tùy chọn trong cam kết 2003-11-09 này , nhưng --preserve-rootchỉ trở thành mặc định trong cam kết 2006-09-03 này , vì vậy trong coreutils 6.2

FreeBSD đã duy trì dấu gạch chéo kể từ lần cam kết 2004-10-04 đó (với "Tìm hiểu xem đồ lót của tôi thực sự chống cháy" như thế nào ), nhưng ban đầu thì khôngPOSIXLY_CORRECT , cho đến khi họ nhớ kiểm tra một thập kỷ sau đó là POSIX bây giờ bắt buộc nó tại điểm mà nó đã được thực hiện ở chế độ POSIX .

Cam kết ban đầu của FreeBSD đề cập Solaris đã thực hiện nó vào thời điểm đó.

@JdePB (trong bình luận bên dưới) đã tìm thấy liên kết đến câu chuyện nội bộ của Sun chứng thực và cung cấp thêm chi tiết về nguồn gốc Solaris và đề nghị Solaris đã có biện pháp bảo vệ trước khi họ đưa ra yêu cầu cho nhóm Austin.

Nó giải thích lý do cho việc thêm loại trừ đó. Mặc dù người ta chỉ có thể tự trách mình nếu họ làm vậy rm -rf /, nhưng có một trường hợp kịch bản có thể làm điều đó nếu làm rm -rf -- "$1/$2"mà không kiểm tra điều đó $1/ $2được cung cấp, đó là điều khiến một số khách hàng của Sun xấu khi sử dụng sai bản vá Solaris (theo liên kết đó).

Việc cấm xóa ...đã được thêm vào từ lâu trước đó và một lần nữa để bảo vệ chống lại những rủi ro tiềm ẩn. rmvẫn là một lệnh nguy hiểm. Nó thực hiện những gì nó có nghĩa là làm: loại bỏ những gì bạn nói với nó.

rm -rf /*
cd /tmp &&  rm -rf .*/   # on some systems where rm -rf ../ still removes
                         # the content of ../ and shells that still
                         # may include . and .. in glob expansions.
rm -rf -- "$diretcory"/* # note the misspelled variable name
dir='foo '; rm -rf $dir/*

Cũng sẽ loại bỏ tất cả mọi thứ. Hoàn thành tên tập tin Shell đã được biết là gây ra vấn đề như vậy khi bạn làm

rm -rf someth<Tab>/*

Mở rộng thành:

rm -rf something /*

Bởi vì somethingnhư vậy đã xảy ra không phải là một thư mục.

Shell thích tcshhoặc zshsẽ thêm một dấu nhắc thêm khi cố gắng gọi rmbằng *ký tự đại diện ( tcshkhông phải theo mặc định).



1
Là một đồng nghiệp trẻ SA, tôi đã thử xóa các tập tin ẩn trong thư mục của người dùng trên SunOS w / rm -rf .*từ thư mục nhà của anh ấy. Ngay sau đó, tất cả các đường dây điện thoại sáng lên ...
Aaron D. Marasco

Tôi đặt cược $ rm -rf. * = Rm -rf / theo cách dễ hiểu để đến đó.
Escoce

@GuruAdrian chắc chắn, * có nghĩa là khớp mọi thứ vì vậy. * = .Filename nhưng cũng ../ và do đó ../ .. và ../../ .. ad infinatum cho đến khi bạn hết bitpace cho lệnh.
Escoce

có thể trong vỏ hiện đại. Không phải lúc nào cũng như vậy. Tôi đã để lại chiều sâu của quản trị và phát triển hệ thống hơn 15 năm trước
Escoce
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.