วิธีการป้องกัน rm จากการรายงานว่าไม่พบไฟล์?


155

ฉันใช้rmสคริปต์ BASH เพื่อลบไฟล์จำนวนมาก บางครั้งไฟล์ไม่มีอยู่ดังนั้นจึงรายงานข้อผิดพลาดมากมาย ฉันไม่ต้องการข้อความนี้ ฉันค้นหาหน้าคนเพื่อหาคำสั่งให้rmเงียบ แต่มีเพียงตัวเลือกเดียวที่ฉันพบคือ-fจากคำอธิบายว่า "ไม่ต้องสนใจไฟล์ที่ไม่มีอยู่ไม่พร้อมรับคำ" ดูเหมือนจะเป็นตัวเลือกที่ถูกต้อง แต่ชื่อดูเหมือนจะไม่พอดี ดังนั้นฉันกังวลว่าอาจมีผลกระทบที่ไม่ตั้งใจ

  • เป็น-fตัวเลือกวิธีที่ถูกต้องที่จะเงียบrm? ทำไมไม่ได้เรียกว่า-q?
  • ตัวเลือกนี้จะทำอะไรอีกหรือไม่

4
คุณไม่ต้องการใช้ -f มันจะลบไฟล์ที่คุณทำเครื่องหมายว่าอ่านแล้วเท่านั้น
พิซซ่า

คำตอบ:


209

การใช้งานหลักของ-fคือการบังคับให้ลบไฟล์ที่จะไม่ถูกลบออกโดยใช้rmตัวเอง (เป็นกรณีพิเศษมัน "ลบ" ไฟล์ที่ไม่มีอยู่จริงจึงระงับข้อความผิดพลาด)

คุณยังสามารถเปลี่ยนเส้นทางข้อความแสดงข้อผิดพลาดโดยใช้

$ rm file.txt 2> /dev/null

(หรือเทียบเท่าระบบปฏิบัติการของคุณ) คุณสามารถตรวจสอบค่า$? ทันทีหลังจากโทรrmเพื่อดูว่าไฟล์ถูกลบจริงหรือไม่


3
--fที่ถูกต้องสำหรับ GNU coreutils แต่เพียงเพราะมันเกิดขึ้นจะเป็นตัวย่อไม่ซ้ำกันสำหรับrm --forceแบบสั้น-fมีความชัดเจนและพกพาได้มากกว่า
Keith Thompson

ไม่แน่ใจด้วยซ้ำ นี่เป็นเพียงสำหรับการพิมพ์ผิด--f -f
chepner

2
2 ในการ2>ทำอะไร
ด่าน

@Maverick มันเปลี่ยนเส้นทางข้อความใด ๆ ที่ส่งไปยัง stderr เพื่อ / dev / null แทนที่จะส่งไปยังสถานี
Benjamin Nolan

73

ใช่-fเป็นตัวเลือกที่เหมาะสมที่สุดสำหรับสิ่งนี้


ระบบบางระบบจะแจ้งให้คุณทราบเมื่อมีพื้นที่ถึง -f จนกว่าคุณจะใช้แบ็กสแลช
vimdude

11
@vimdude: ไม่ใช่ "บางระบบ"; พฤติกรรมที่แสดงให้เห็นว่าคุณมีฟังก์ชั่นเปลือกหรือนามแฝงที่แมปไปrm rm -i
Keith Thompson

28

-f เป็นธงที่ถูกต้อง แต่สำหรับผู้ดำเนินการทดสอบไม่ใช่ rm

[ -f "$THEFILE" ] && rm "$THEFILE"

สิ่งนี้ทำให้มั่นใจได้ว่าไฟล์มีอยู่และเป็นไฟล์ปกติ (ไม่ใช่ไดเรกทอรีโหนดอุปกรณ์ ฯลฯ ... )


4
อย่างไรก็ตามนี่เป็นสภาวะการแข่งขันและไม่ควรใช้ในสคริปต์การผลิต
tripleee

ฉันเชื่อว่า @tripleee กำลังชี้ให้เห็นว่าการทดสอบ "-f" และการลบไฟล์อาจเสร็จสมบูรณ์ตามลำดับใด ๆ อีกวิธีที่จะทำคือ: if [ -f "$THEFILE" ]; then rm "$THEFILE"; fiซึ่งทำให้การทดสอบและขั้นตอนการลบไฟล์เรียงตามลำดับอย่างชัดเจน
robla

2
@robla รหัสนั้นทำสิ่งเดียวกันกับไวยากรณ์ verbose มากขึ้น ... &&! = & ... การทดสอบจะเกิดขึ้นก่อน rm เสมอ แต่กระบวนการแยกต่างหากสามารถทำได้ในทางเทคนิค (แต่ไม่น่าจะเป็นไปได้มาก) ลบมันก่อนที่ rm จะทำงาน (ในขณะที่เชลล์ รหัสหลังจากการทดสอบจะถูกตีความ)
technosaurus

เทคโนซอรัส - โอ๊ะโอเคคุณพูดถูก คุณคิดว่าคำตอบที่ดีที่สุดสำหรับคำถามของ @ mmlac คืออะไร
robla

3
และเพียงเพื่อยืนยันสภาพการแข่งขันเป็นว่าสิ่งที่สามารถลบไฟล์ระหว่างและtest ก่อนหน้าrmนี้ไม่มีวิธีที่rmจะดำเนินการtestได้ ก่อนที่คุณจะเผ่นเป็นความผิดพลาดทั่วไปในการเขียนโปรแกรมพร้อมกัน - คุณไม่สามารถไว้วางใจผลลัพธ์ของ "ลุค" ได้อีกต่อไปเมื่อคุณ "กระโดด" จริง ๆ ; วิธีแก้ปัญหาคือใช้การล็อคหรือการทำงานแบบปรมาณู ซึ่งแน่นอนว่าทำไมคุณต้องการrm -fซึ่งเป็นตัวอย่างของหลัง
tripleee

13

\rm -f file จะไม่รายงานไม่พบ


4
-r นั้นไม่จำเป็นและอันตราย
mahemoff

1
ฉันคิดว่าหลายไฟล์หรือไดเรกทอรี อ่านคำขอของผู้ใช้อีกครั้งและคุณพูดถูกเขาขอไฟล์เท่านั้น แก้ไขคำตอบของฉันแล้ว
vimdude

แบ็กสแลชคืออะไรก่อนที่ RM จะทำอะไร ?? ได้โปรดฉันต้องการคำตอบ สำหรับ windows cygwin รุ่น make 4.1 ไม่สามารถจัดการกับ \ rm ได้ในขณะที่ 3.75 ใช้ได้ดี
Ayman Salah

2
@AymanSalah แบ็กสแลชในบริบทนี้จะหลบเลี่ยงการทำงานหรือนามแฝงที่ห่อหุ้มของจริงrm(ซึ่งเป็นที่นิยมในบางไซต์ในต้นปี 1990 เพื่อป้องกันไม่ให้ผู้เริ่มต้นเริ่มต้นลบสิ่งต่าง ๆ แล้วเรียกดูแลระบบเพื่อรับไฟล์
tripleee

ขอบคุณ - นี่ช่วยแก้ไขปัญหาของฉัน .. เห็นได้ชัดว่ารหัสทางออกอนุญาตให้ผูกมัดการใช้&&ในขณะที่ไม่มี -f มันจะหยุดพักเมื่อไม่พบไฟล์
Igor

5

เท่าที่rm -fทำ "สิ่งอื่น" ก็ไม่แรง ( -fเป็นชวเลข--force) กำจัดเงียบอยู่ในสถานการณ์ที่rmอาจจะขอให้คุณยืนยัน ตัวอย่างเช่นเมื่อพยายามลบไฟล์ที่คุณไม่สามารถเขียนได้จากไดเรกทอรีที่คุณเขียนได้


-9

ฉันมีปัญหาเดียวกันสำหรับ cshell ทางออกเดียวที่ฉันมีคือการสร้างไฟล์จำลองที่ตรงกับรูปแบบก่อนหน้า "rm" ในสคริปต์ของฉัน


7
นั่นเป็นทางออกเดียวหรือไม่ คุณลองrm -fหรือrm filename >&/dev/null?
Keith Thompson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.