ตั้งแต่เมื่อ POSIX และ GNU rm ไม่ลบ /?


23

เป็นเวลาหลายปีแล้วที่rmยูทิลิตี้GNU จะไม่ลบ/จนกว่าจะมีการเรียกพร้อมกับ--no-preserve-rootตัวเลือก อย่างไรก็ตามคำสั่งrm -rf /ดังกล่าวถูกขังอยู่ในจิตใต้สำนึกส่วนรวมว่าเป็นอันตรายมาเป็นเวลานานและผู้คนก็มักจะอ้างว่ามันเป็นคำสั่ง "น่ากลัว"

ฉันสงสัยว่าเมื่อกฎนี้ที่rmไม่สามารถลบ/ปรากฏขึ้นครั้งแรก ฉันตรวจสอบรายละเอียด POSIX แล้วและฉันสามารถเห็นได้ว่าในขณะที่POSIX: 2008มีคุณสมบัติความปลอดภัยนี้POSIX: 2001จะไม่ทำงาน เนื่องจากข้อมูลจำเพาะ POSIX เวอร์ชันออนไลน์ได้รับการอัปเดตเป็นครั้งคราวด้วยการเปิดตัวย่อยใหม่แต่ละครั้งฉันจึงตรวจสอบเครื่อง wayback และพบหน้าเว็บที่เกี่ยวข้องของ POSIX: 2008 จากปี 2010และสามารถยืนยันได้ว่ากฎที่rmไม่สามารถลบได้/ได้รับการจดทะเบียนแล้ว

ดังนั้นคำถามของฉันคือ:

  • เมื่อใดที่กฎที่rmไม่สามารถลบการ/เพิ่มลงในข้อมูลจำเพาะ POSIX ได้ มันเป็นรุ่น 2008 ของ Single UNIX Specification เวอร์ชั่น 4 หรือเพิ่มเข้ามาในการแก้ไขไหม?
  • ข้อ จำกัด นี้ถูกเพิ่มลงใน GNU เมื่อrmใด ฉันค่อนข้างแน่ใจว่าก่อนที่มันจะถูกเพิ่มใน POSIX แต่เมื่อมันเกิดขึ้น?


1
ที่เกี่ยวข้อง: การตีความกลุ่มออสติน # 019 (2003) ซึ่งอธิบาย (แต่ไม่ได้ใช้) การเปลี่ยนแปลง
Michael Homer

คำตอบ:


28

คุณสามารถค้นหารุ่น HTML ของ POSIX 2008 ทุกรุ่นทางออนไลน์:

ที่ถูกเพิ่มเข้ามาในรุ่น 2008

corrigenda ทางเทคนิคโดยทั่วไปจะไม่เพิ่มคุณสมบัติใหม่

คุณสามารถดูรุ่นก่อนหน้า ( http://pubs.opengroup.org/onlinepubs/009695399/utilities/rm.html ) (POSIX 2004) ไม่มีข้อความนั้น

ข้อความใหม่ได้รับการยอมรับในการประชุมกลุ่มออสตินระหว่างปี 2003-05-09เพื่อรวมไว้ในการแก้ไขมาตรฐานในภายหลัง

มันได้รับการร้องขอจากจอห์นเบ็คของ Sun Microsystems มีนาคมปีเดียวกัน (ลิงค์จำเป็นต้องลงทะเบียน opengroup เห็นการเพิ่มประสิทธิภาพขอหมายเลข 5 ที่นี่ )

John Beck เขียนเมื่อวันอังคารที่ 11 มีนาคม 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เพิ่ม--preserve-rootและ--no-preserve-rootตัวเลือกในการกระทำนี้ 2003-11-09แต่--preserve-rootกลายเป็นค่าเริ่มต้นในการกระทำนี้ 2006-09-03ดังนั้นใน coreutils 6.2

FreeBSD รักษาสแลชตั้งแต่ปี2004-10-04 กระทำ (กับ"ค้นหาว่าชุดชั้นในของฉันคือเปลวไฟที่พิสูจน์ได้จริง ๆ "แต่บันทึกตอนแรกไม่ได้อยู่ภายใต้POSIXLY_CORRECTจนกระทั่งพวกเขาจำได้ว่าจะตรวจสอบอีกสิบปีต่อมาว่า POSIX อิงมันจุดที่มันทำยังอยู่ในโหมด POSIX

FreeBSD เริ่มต้นกล่าวถึง Solaris ว่าได้ทำไปแล้วในเวลานั้น

@JdePB (ในความคิดเห็นด้านล่าง) พบว่าลิงก์ไปยังเรื่องราวภายในวงอาทิตย์ยืนยันและให้รายละเอียดเพิ่มเติมเกี่ยวกับต้นกำเนิดโซลาริสและแนะนำโซลาริสมีการปกป้องอยู่ก่อนที่พวกเขาจะขอกลุ่มออสติน

มันอธิบายถึงเหตุผลในการเพิ่มการยกเว้นนั้น ในขณะที่ใครคนหนึ่งสามารถตำหนิตัวเองได้หากพวกเขาทำrm -rf /มีกรณีที่สคริปต์สามารถทำได้ถ้าทำrm -rf -- "$1/$2"โดยไม่ตรวจสอบว่า$1/ $2ถูกจัดเตรียมไว้ซึ่งเป็นสิ่งที่ทำให้ลูกค้าของ Sun บางคนแย่เมื่อทำการติดตั้ง patch ของ Solaris ผิดพลาด

การห้ามการลบ.และ..ถูกเพิ่มมานานก่อนหน้านั้นและอีกครั้งเพื่อป้องกันอุบัติเหตุที่อาจเกิดขึ้น rmยังคงเป็นคำสั่งที่อันตราย มันทำในสิ่งที่มันควรทำ: ลบสิ่งที่คุณบอก

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/*

ก็จะลบทุกอย่าง การรู้จักชื่อไฟล์ของเชลล์ทำให้เกิดปัญหาดังกล่าวเมื่อคุณทำ

rm -rf someth<Tab>/*

ขยายเป็น:

rm -rf something /*

เพราะsomethingอย่างนั้นเกิดขึ้นไม่ต้องเป็นไดเรกทอรี

เชลล์ชอบtcshหรือzshจะเพิ่มพรอมต์พิเศษเมื่อพยายามโทรrmด้วย*อักขระตัวแทน ( tcshไม่ใช่ค่าเริ่มต้น)



1
ในฐานะเพื่อนร่วมงาน SA ฉันพยายามลบไฟล์ที่ซ่อนอยู่ในไดเรกทอรีของผู้ใช้บน SunOS ด้วย / rm -rf .*จาก dir บ้านของเขา หลังจากนั้นไม่นานสายโทรศัพท์ทั้งหมดก็สว่างขึ้น ...
Aaron D. Marasco

ฉันเดิมพัน $ rm -rf. * = rm -rf / ในวิธีที่ซับซ้อนเพื่อไปที่นั่น
Escoce

@GuruAdrian แน่ใจว่า * หมายถึงจับคู่ทุกอย่างอย่างนั้น * = .filename แต่ยัง ../ และดังนั้น ../ .. และ ../ ../ .. ad infinatum จนกว่าคุณจะหมดบิตสเปซสำหรับคำสั่ง
โก

อาจจะเป็นกระสุนสมัยใหม่ มันไม่ได้เป็นอย่างนั้นเสมอไป ฉันปล่อยให้ความลึกของการดูแลระบบและการพัฒนามากกว่า 15 ปีที่ผ่านมา
โก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.