rm ไม่ได้รายงานเมื่อไฟล์หายไปหรือไม่


38

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

นอกจากนี้ยังมีคำสั่งที่ดีกว่าให้ใช้เพื่อลบไฟล์ที่มีเสียงดังน้อยลงหรือไม่

คำตอบ:


65

ใช้-fตัวเลือก มันจะละเว้นไฟล์ที่ไม่มีอยู่อย่างเงียบ ๆ

จากman rm:

   -f, --force
          ignore nonexistent files and arguments, never prompt

[ส่วนที่ไม่พร้อมรับคำหมายความว่า (a) -fแทนที่ตัวเลือก-iหรือ-Iตัวเลือกก่อนหน้านี้และ (b) ไฟล์ที่ป้องกันการเขียนจะถูกลบโดยไม่ต้องขอ]

ตัวอย่าง

โดยไม่-f, rmจะบ่นเกี่ยวกับไฟล์ที่ขาดหายไป:

$ rm nonesuch
rm: cannot remove ‘nonesuch’: No such file or directory

ด้วย-fมันจะเงียบ:

$ rm -f nonesuch
$

4
โอ้ฉันใหม่ที่ไม่พรอมต์ให้ลบออกไม่ได้ตระหนักว่ามันไม่ได้สนใจใครเลย ฉันข้ามไปโดยสิ้นเชิงเมื่อมองผู้ชาย :-) ขอขอบคุณ. ฉันจะทำเครื่องหมายคำตอบนี้เป็นคำตอบโดยเร็วที่สุด
flickerfly

9

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

# rest of script
# ...
[ -e "$file" ] && rm "$file"
# ...
# rest of script

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

ในกรณีที่คุณต้องการใช้ความคิดเดียวกันกับไฟล์หลายไฟล์ฉันจะสร้างนิยามฟังก์ชั่นเช่น:

qrm() {
  for f
  do
    [ -e "$f" ] && rm "$f"
  done
}

ใช้มันเหมือน: qrm file1 file2-does-not-exist *.txt etc here


1
เป็นเรื่องที่ควรตระหนักถึงโอกาสที่น้อยมากที่สภาพการแข่งขันที่ไฟล์ถูกลบ (หรือสร้าง) ระหว่างการทดสอบและการลบ แต่ฉันไม่สามารถจินตนาการได้ว่ามีความเกี่ยวข้องในสถานการณ์ทั่วไปที่จะใช้เชลล์สคริปต์ .
David Z

7

คุณระบุว่าคุณยังคงต้องการที่จะเห็นผลลัพธ์อื่น ๆ จากrmคำสั่งเมื่อคุณเรียกใช้ แต่การใช้-fตัวเลือกจะระงับเหล่านั้น คุณจะต้องกรอง STDERR สำหรับสิ่งที่คุณต้องการซึ่งค่อนข้างยุ่งยากหากคุณต้องการให้ทุกอย่างปรากฏขึ้น

คุณจะต้องการใช้คำสั่งเช่นนี้:

rm -f filename 3>&1 1>&2 2>&3 3>&- | grep -v 'No such file or directory'

คำสั่งอธิบาย:

  • -f อาร์กิวเมนต์คือบังคับให้ผ่านและไม่พร้อมต์ให้ยืนยันหรือข้อผิดพลาด
  • 3>&1 1>&2 2>&3 3>&-คือการสลับรอบ STDOUT และ STDERR สำหรับการกรอง (คุณสามารถอ่านรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้ที่นี่ถ้าต้องการ
  • | grep -v 'No such file or directory' กำลังกรองข้อความที่คุณไม่ต้องการเห็น

ตอนนี้ถ้าคุณเพียงแค่ต้องการที่จะระงับข้อความผิดพลาดทั้งหมดคุณสามารถเรียกใช้คำสั่งต่อไปนี้:

rm filename 2> /dev/null

คำสั่งนี้เปลี่ยนเส้นทาง STDERR ไปยัง / dev / null ดังนั้นคุณจะไม่เห็นมันเมื่อคุณเรียกใช้คำสั่ง


1
(AFAICS) rmโดย-vไม่ส่งผลลัพธ์ไปที่ stdout เพียง stderr ดังนั้นในกรณีนี้คุณสามารถทำได้2>&1 | grepโดยที่ไม่มีการเต้นรำซึ่งมีประโยชน์มากกว่าโดยทั่วไป
dave_thompson_085

4

คุณสามารถใช้findคำสั่งพร้อมกับ-deleteตัวเลือก จะเป็นการลบไฟล์ที่พบดังนั้นจึงไม่เคยเตือนหากไม่มี ตัวอย่างอาจเป็น:

find /var/log/triffids/ -name "*.log" -mtime 30 -delete

ซึ่งจะค้นหา/var/log/triffids/ไดเรกทอรีและลบไฟล์ทั้งหมดด้วย.logคำต่อท้ายซึ่งไม่ได้รับการแก้ไขนานกว่า 30 วัน

มันเป็นความคิดที่ดีที่จะเรียกใช้คำสั่งเหล่านี้ได้โดยไม่ต้อง-deleteตัวเลือกแรกที่จะทำให้แน่ใจว่ามันหาไฟล์ที่คุณคาดหวัง


ฉันชอบตัวเลือกนี้และจะพิจารณาการเปลี่ยนแปลง ขอขอบคุณที่แบ่งปัน
flickerfly

3

ตรวจสอบ--force( -f) ตัวเลือกในการrm:

-f, --force

ละเว้นไฟล์และอาร์กิวเมนต์ที่ไม่มีอยู่และไม่มีพร้อมท์


2

นี่คือแฮ็ค แต่คุณสามารถtouchลบไฟล์ได้ตลอดเวลา หากไม่มีอยู่มันจะถูกสร้างขึ้นเพื่อให้rmสามารถลบออกได้


ฉันชอบสิ่งนี้ยกเว้นเรื่องประสิทธิภาพ - มันมีราคาแพงแค่ไหนในการสัมผัสไฟล์ K หลาย ๆ ไฟล์เมื่อเทียบกับการลบไฟล์ที่ไม่มีอยู่เท่านั้น?
Dani_l

0

คุณสามารถใช้งาน-fได้ตามที่ผู้ใช้ต้องการ:

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

rm -f xyz-directory

จะไม่เตือนคุณและจะทำสิ่งที่คุณต้องการ


-1

มีสองวิธีหลัก: หากคุณเพิ่มตัวเลือก -f มันจะไม่แสดงข้อผิดพลาด "ไม่มีอยู่" และสอง: (ใช้ได้กับคำสั่งเกือบทุกคำ) แทนการทำ "คำสั่ง" ทำ "คำสั่ง 2> / dev / null "โดยที่" thecommand "เป็นคำสั่งที่คุณใช้


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