หา - exec rm กับ -delete


260

ฉันพยายามเข้าใจความแตกต่างระหว่างสองคำสั่งนี้:

sudo find / -name .DS_Store -delete

และ

sudo find / -name ".DS_Store"  -exec rm {} \;

ฉันสังเกตเห็นว่าexecวิธีนี้เป็นที่ต้องการ ทำไม? อันไหนปลอดภัยกว่า / เร็วกว่า / ดีกว่า ฉันใช้ทั้งMacbookแล้วดูเหมือนว่าทุกอย่างจะทำงานได้ดี

คำตอบ:


245

-delete จะทำงานได้ดีขึ้นเพราะไม่ต้องวางกระบวนการภายนอกสำหรับไฟล์ที่ตรงกันแต่ละไฟล์

มันเป็นไปได้ว่าคุณอาจจะเห็น-exec rm {} \;มักจะแนะนำเพราะไม่ได้อยู่ในทุกรุ่นของ-delete findฉันไม่สามารถตรวจสอบได้ในตอนนี้ แต่ฉันค่อนข้างแน่ใจว่าฉันใช้ตัวเลือกที่findไม่มีมัน

ทั้งสองวิธีควรจะ "ปลอดภัย"

แก้ไขต่อความคิดเห็นจาก @doitmyway: ตรวจสอบให้แน่ใจว่าคุณได้จับคู่ชื่อแล้วลบไม่ใช่วิธีอื่น (ลบแล้วจับคู่) มิฉะนั้นไฟล์ทุกไฟล์จะถูกลบไม่ว่าจะตรงกันหรือไม่ก็ตาม กล่าวคือไม่find / -delete -name .DS_Storeทำเช่นนี้:

วิธีการทั่วไปในการหลีกเลี่ยงค่าใช้จ่ายในการวางไข่กระบวนการภายนอกสำหรับแต่ละไฟล์ที่ตรงกันคือ:

find / -name .DS_Store -print0 | xargs -0 rm

(แต่โปรดทราบว่ามีปัญหาเรื่องการพกพาที่นี่เช่นกัน: ค้นหาทุกรุ่นไม่มี-print0!)


2
ฉันเห็น. ฉันได้อ่านด้วยการใช้-deleteสวิตช์ก่อนที่จะ-nameลบทรีไฟล์ที่ระบุดังนั้นฉันเดาว่าต้องระวัง
หัวหอม

8
เมื่อเร็ว ๆ นี้findคุณสามารถใช้-exec rm {} +เพื่อลบไฟล์ที่ตรงกันทั้งหมดด้วยrmคำสั่งเดียว
jimmij

3
.DS_Storeไม่มีอักขระพิเศษเลยราคาจึงไม่จำเป็นและไม่ต้องเปลี่ยนแปลงอะไรในกรณีนี้
Celada

1
โดยทั่วไปเพียงช่องว่าง (ช่องว่างแท็บหรืออื่น ๆ ) เป็นสิ่งเดียวที่ทำให้สตริงที่ไม่มีเครื่องหมายถูกตีความว่าเป็นอาร์กิวเมนต์บรรทัดคำสั่งแยกกันสองรายการ แต่นั่นไม่ใช่ทั้งหมดที่คุณต้องขออภัยเมื่อตัดสินใจว่าจะพูดหรือไม่ คุณต้องกังวลเกี่ยวกับทุก metacharacters เปลือกเช่น;หรือ|หรือ>หรือ<และ `` และอื่น ๆ อีกมากมายที่มีความหมายพิเศษกับเปลือกนอกเสียจากว่าที่ยกมา
Celada

1
@MarcoMarsala xargsดูแลปัญหารายการอาร์กิวเมนต์ที่มีขนาด จำกัด อย่างโปร่งใสโดยแบ่งมันออกเป็นหลายการร้องขอของคำสั่ง
Celada

27

สมมติว่า.DS_Storeเป็นตัวแทนของไฟล์ไม่ใช่ไดเรกทอรีวิธีพกพาที่รวดเร็วที่สุดในการดำเนินการคือ:

sudo find / -name .DS_Store -exec rm {} +

ความเสี่ยงเพียงอย่างเดียวคือsudoไม่ให้มี แต่ตอนนี้ค่อนข้างต่ำ

-deleteตัวเลือกที่ใช้ในการเรียกร้อง GNU ค้นหาและยังคงไม่ได้มาตรฐานในการอื่น ๆ อีกมากมายfindการใช้งานจึงไม่สามารถใช้ได้เสมอ

การยกเลิกคำสั่ง+แทนคำสั่งที่\;ปรับให้เหมาะสมสูงสุดexecโดยไม่ได้รันrmคำสั่งสำหรับแต่ละรายการที่.DS_Storeมีอยู่ในระบบไฟล์


16

สำหรับเครื่องเช่น macbook ของคุณคุณจะไม่พบความแตกต่างด้านประสิทธิภาพระหว่างสองคำสั่ง อย่างไรก็ตามหากคุณดูที่รุ่น -exec คุณสามารถเห็นความแตกต่างเล็กน้อย:

sudo find / -iname ".file-to-delete"  -exec rm {} \;

ซึ่งหมายความว่าคุณจะพบไฟล์ทั้งหมดที่มีชื่อ ".file-to-delete" อย่างไรก็ตามการค้นหานี้อาจส่งคืนผลบวกปลอมที่ไม่พึงประสงค์ เมื่อทำอะไรกับ sudo คุณควรระวังให้มากขึ้น ข้อดีของการใช้ -exec rm {} คือคุณสามารถส่งอาร์กิวเมนต์ไปยัง rm ดังนี้:

sudo find / -iname "*~"  -exec rm -i {} \;

ในตัวอย่างนี้ฉันต้องการลบไฟล์สำรองที่ emacs ทำ อย่างไรก็ตามตัวหนอนอาจอยู่ในไฟล์คลุมเครือบางอย่างที่ฉันไม่รู้และอาจมีความสำคัญ บวกฉันต้องการยืนยันการลบ ดังนั้นฉันจึงใส่ตัวเลือก '-i' ในคำสั่ง rm สิ่งนี้จะทำให้ฉันลบแบบโต้ตอบ

นอกจากนี้คุณสามารถปรับแต่งการใช้ rm เพื่อลบไดเรกทอรีรวมถึงไฟล์:

find /usr/local/share/ -iname "useless" -exec rm -r {} \;

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


3
ดูเพิ่มเติม -ok rm {} \;ที่-exec rm {} \;สำหรับการยืนยันแบบโต้ตอบ
Kusalananda
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.