ล่าสุด ( ณ 2017) รุ่นของข้อมูลจำเพาะ POSIX สำหรับrm
ยูทิลิตี้ที่นี่ (และก่อนหน้านี้หนึ่งมี ) และห้ามลบและ.
..
หากไฟล์จุดใดจุดหนึ่งหรือจุดจุดถูกระบุเป็นส่วน basename ของตัวถูกดำเนินการ (นั่นคือองค์ประกอบชื่อพา ธ สุดท้าย) หรือถ้าตัวถูกดำเนินการแก้ไขไปยังไดเรกทอรีราก, RM จะเขียนข้อความวินิจฉัยข้อผิดพลาดมาตรฐานและไม่ทำอะไรเลย มากขึ้นด้วยตัวถูกดำเนินการ
ตามที่ระบุไว้โดย @jlliagre ส่วนที่เกี่ยวกับ/
การเพิ่มใน SUSv4
ข้อมูลจำเพาะ Unix ที่เปิดเผยต่อสาธารณชนที่เก่าแก่ที่สุดที่ฉันสามารถหาได้ ( XPF4 CAE rev2 (1994)) ได้ระบุไว้แล้ว.
และ..
ไม่สามารถลบออกได้แม้ว่าความคิดเห็นใน GNU fileutils changelog แนะนำว่าเป็นกรณีใน POSIX รุ่นเก่า
โปรดทราบว่ามันใช้กับdir/..
และ../
เช่นกัน แต่การใช้งานบางอย่าง (รวมถึงการรับรอง UNIX เช่น Solaris 11 และ macOS) ยังคงไม่ได้ป้องกันrm -rf ../
หรือrm -rf .*/
)
ประวัติศาสตร์
ก่อนเริ่ม
-r
ตัวเลือกที่จะrm
ถูกเพิ่มเข้ามาในระบบปฏิบัติการยูนิกซ์ V3 (1973) แม้ว่ามันจะเป็นเพียงการลบเนื้อหาของไดเรกทอรีที่คุณยังคงจำเป็นต้องใช้rmdir
ในการลบไดเรกทอรี
สิ่งนั้นเปลี่ยนไปใน Unix V7 (1979, รุ่นที่เปิดตัว Bourne shell และ Unices ส่วนใหญ่ได้รับมา) rm -r
ตอนนี้ลบไดเรกทอรีเช่นกันและจะไม่ลบ..
ทรีไดเรกทอรี หน้าคนฯ :
ห้ามมิให้ลบไฟล์..
เพื่อหลีกเลี่ยงผลกระทบต่อต้านสังคมโดยไม่ได้ตั้งใจทำบางสิ่งเช่นrm -r .*
นั้น
(แม้ว่าบางคนอาจโต้แย้งว่าrm -r .*
ยังคงต่อต้านสังคมเพราะมันลบทุกอย่างเพราะ.
รวมอยู่)
มันก็ยังยอมรับที่จะลบ.
แม้ว่ามันจะไม่ยกเลิกการเชื่อมโยง.
หรือ..
รายการ ดังนั้นจึงrm -r .
เป็นวิธีที่มีประสิทธิภาพในการล้างไดเรกทอรีปัจจุบัน
นอกจากนี้ทราบว่าการป้องกันเป็นเพียงสำหรับตัวอักษร..
โต้แย้งไม่ได้สำหรับการหรือdir/..
./..
ดังนั้นrm -rf ./.*
จะยังคงลบทุกอย่างในไดเรกทอรีหลักซ้ำ
เป็นที่น่าสนใจที่จะเห็นว่านั่นเป็นวิธีที่จะแก้ไขข้อผิดพลาด / ความผิดพลาดที่ globs สามารถรวม.
และ..
ในการขยายตัวของพวกเขา ที่ได้รับการแก้ไขใน Forsyth shell (พื้นฐานสำหรับ Minix shell และ pdksh เดิม) ในช่วงปลายยุค 80, zsh
(1990) และfish
(2005) แต่ไม่ใช่ shell อื่น ๆ และโดยเฉพาะอย่างยิ่งไม่ใช่sh
ภาษาPOSIX ที่ต้องการการขยาย.*
รวม.
และ..
ถ้า พวกเขาจะถูกส่งกลับโดยreaddir()
( bash
แก้ไขปัญหาส่วนหนึ่งเท่านั้นshopt -s dotglob
ที่ที่ globs (ยกเว้น.xxx
คน) ไม่รวม.
หรือหรือ..
ด้วยksh
และคุณสามารถแก้ไขได้โดยการทำFIGNORE='@(.|..)'
)
เมื่อการห้าม.
เช่นกันถูกเพิ่มเข้ามาไม่ชัดเจนและแตกต่างกันไปตามแต่ละยูนิกซ์ ข้อค้นพบบางประการด้านล่าง
BSDs
การห้าม.
ถูกเพิ่มเข้ามาระหว่าง 2.9BSD (1983) และ 2.10BSD (1987) และระหว่าง 4.2BSD (1983) และ 4.3BSD (1986) (ดูการเปลี่ยนแปลงนี้ประทับเวลา 1985 ใน unix-history-repo )
$ wget -qO- http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.9BSD/root.tar.gz |
zgrep -ao 'rm: canno[[:print:]]*'
rm: cannot remove `..'
$ wget -qO- http://www.tuhs.org/Archive/PDP-11/Distributions/ucb/2.10bsd.tar.gz |
zgrep -ao 'rm: canno[[:print:]]*'
rm: cannot remove `.' or `..'
rm: cannot remove `.' or `..'\n");
สำหรับdir/.
และdir/..
ดูการเปลี่ยนแปลงนี้ในปี 1988 (BSD 4.3 สุทธิ / 1)
จนถึงวันนี้rm
FreeBSD (และอนุพันธ์เช่น macOS) ยังคงว่างเปล่าไดเรกทอรีปัจจุบันหรือไดเรกทอรีหลักขึ้นอยู่กับrm -rf ./
หรือrm -rf ../
(สำคัญสำหรับrm -rf .*/
)
ระบบ V
ฉันไม่ได้รับข้อมูลมากนักเนื่องจาก AT&T Unix ไม่ได้ใช้แหล่งข้อมูลหรือไบนารีสำหรับ V7 ในคู่มือออนไลน์ HPUX (ตาม System III) ยังคงกล่าวถึงว่าห้ามเพียงอย่างเดียว..
ในขณะที่มันห้ามอย่างมีประสิทธิภาพซึ่งเป็นสิ่งบ่งชี้ว่าอย่างน้อย SysIII ไม่ได้ห้ามการลบ.
( แก้ไข : ตอนนี้ดูซอร์สโค้ดSysIIIrm
แล้ว แทบไม่มีการเปลี่ยนแปลงตั้งแต่ Unix V7)
คู่มือออนไลน์อื่น ๆ ทั้งหมดที่ฉันได้ตรวจสอบพูดถึงการลบ.
หรือ..
ถูกห้ามซึ่งคาดว่าจะเป็นไปตาม POSIX
โซลาริสrm
ยังคงเทไดเรกทอรีปัจจุบันหรือผู้ปกครองเมื่อหรือrm -rf ./
rm -rf ../
GNU
การเปลี่ยนแปลงก่อนหน้าสำหรับไฟล์ GNUมีข้อมูลประวัติทั้งหมด
ในขณะที่เดิมไม่ได้ลบ.
หรือ..
ถูกห้าม..
ถูกห้ามก่อนแล้วทั้งสอง (รวมถึงdir/.
) ทั้งหมดระหว่างปี 1990 และ 1991
อื่น ๆ
อย่างที่เราเห็นในzsh
การขยายตัวของ.*
(หรือกลมใด ๆ ) ไม่เคยมี.
หรือ..
(แม้ในsh
โหมดการจำลอง) rm
builtin (ซึ่งคุณจะได้รับถ้าคุณzmodload zsh/files
) ดังนั้นจึงไม่รักษา.
หรือ..
เป็นพิเศษ ดังนั้นด้วยความที่zsh
ในตัวคุณสามารถrm -rf .
หรือrm -rf ..
จะว่าง.
หรือ..
แต่rm -rf .*
จะไม่ลบหรือ.
..
ใน busybox rm
การห้ามการลบ.
และ..
ถูกเพิ่มใน 0.52 (2001)
rm
แต่ฉันคิดว่ามันเป็นมูลค่าการกล่าวขวัญว่าคุณยังสามารถมีผลที่ไม่คาดคิดกับchmod
,chown
ฯลฯ.*
เมื่อจับคู่