ฉันจะทำให้ rm ไม่ให้ข้อผิดพลาดได้อย่างไรหากไม่มีไฟล์อยู่?


329

ฉันกำลังเขียน makefile ที่จะล้างไฟล์ที่ไม่มีประโยชน์เมื่อสิ้นสุดการคอมไพล์ หากเป้าหมายได้ถูกสร้างขึ้นแล้วแน่นอนว่ามันจะข้ามเป้าหมายนั้นและไฟล์ที่ไร้ประโยชน์อาจไม่อยู่ที่นั่น ดังนั้นถ้าฉันทำสิ่งนี้:

rm lexer.ml interpparse.ml interpparse.mli

ฉันอาจได้รับข้อผิดพลาดเนื่องจากไม่มีไฟล์ใดไฟล์หนึ่งอยู่ มีวิธีบอกrmให้เพิกเฉยกับไฟล์เหล่านี้หรือไม่?

ในการอ่าน man page ฉันเห็นตัวเลือกต่อไปนี้:

 -f          Attempt to remove the files without prompting for confirma-
             tion, regardless of the file's permissions.  If the file does
             not exist, do not display a diagnostic message or modify the
             exit status to reflect an error.  The -f option overrides any
             previous -i options.

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


คุณลองบางอย่างrmในกล่องทรายหรือไม่? ดูเหมือนว่า-fจะทำสิ่งที่คุณต้องการโดยไม่คำนึงถึงความโค้งมน
JMD

หากการอนุญาตไม่อนุญาตให้ใช้-fตัวเลือกrm จะยังคงพยายามลบอยู่ มันจะล้มเหลว มันจะไม่บอกคุณว่ามันล้มเหลว มีประโยชน์ถ้าชื่อไฟล์เป็นตัวแปรหรือกลม
LawrenceC

เพียงเพื่อความสมบูรณ์: มีสิ่งrm --interactive=neverที่ทำหน้าที่rm -fยกเว้นมันจะกลับสถานะทางออกข้อผิดพลาด ดูที่นี่สำหรับรายละเอียดเพิ่มเติม: unix.stackexchange.com/questions/72864/…
lesmana

คำตอบ:


282

-fตัวเลือกแน่นอนสิ่งที่คุณต้องการจะใช้

การยืนยันเกี่ยวกับการอนุญาตของไฟล์ที่อ้างถึงคือ:

$ touch myfile    
$ chmod 400 myfile
$ rm myfile       
rm: remove write-protected regular empty file `myfile'?

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


1
ส่วนใหญ่ แต่ไม่ใช่ทุกระบบจะถาม (ฉันคิดว่า) -iบางอย่างต้องใช้
DaveParillo

1
หากคุณต้องการให้ข้อความแสดงข้อผิดพลาด แต่ไม่รหัสข้อผิดพลาดออกจากดูคำตอบโดยGiel Berkers ฉันใช้set -eในสคริปต์ทุบตีของฉันทั้งหมดเพื่อให้สคริปต์ออกจากหลังจากคำสั่งใด ๆ ให้ข้อผิดพลาด ฉันมักต้องการให้สคริปต์บอกฉันว่าrmมีข้อผิดพลาดหรือไม่ แต่ดำเนินการต่อไป อย่างต่อเนื่อง
cledoux

124

อีกวิธีหนึ่งคือ: https://stackoverflow.com/questions/11231937/bash-ignoring-error-for-a-particular-command

เพียงเพิ่มคำสั่งหรือหลังคำสั่งของคุณ:

rm -rf my/dir || true

วิธีนี้เมื่อคำสั่ง # 1 ล้มเหลว (พ่นข้อผิดพลาด) คำสั่งเรียกใช้ # 2 trueซึ่งเป็นเพียง


4
มันพิมพ์ข้อผิดพลาดและดำเนินการต่อซึ่งเป็นที่ต้องการสำหรับกรณีของฉัน
worldsayshi

9
หรือเพียงrm -rf my/dir ||:เพื่อให้รัดกุมยิ่งขึ้น ( :ย่อมาจากtrue)
Godsmith

ทางออกที่ดีกว่าในความคิดของฉัน สามารถมองเห็นได้อย่างง่ายดายว่าเกิดอะไรขึ้นและทำไมรหัสผลลัพธ์จึงถูกละเว้น ฉันชอบมัน!
Mavamaarten

76

ฉันไปงานปาร์ตี้ช้า แต่ฉันใช้สิ่งนี้ตลอดเวลา ใน makefile เพิ่ม-ไปยังจุดเริ่มต้นของบรรทัดเพื่อละเว้นค่าส่งคืนของบรรทัดนั้น ชอบมาก

-rm lexer.ml interpparse.ml interpparse.mli

9
นี่จะยังพิมพ์ข้อผิดพลาดไปยังคอนโซลซึ่งจะฝึกให้คุณละเว้นข้อผิดพลาดในผลลัพธ์ของการทำซึ่งอาจไม่ใช่สิ่งที่คุณต้องการ rm -rf เป็นตัวเลือกที่ดีกว่าในความคิดของฉัน
Godsmith

@Godsmith ฉันควรละเว้นข้อผิดพลาดมากกว่าการบังคับให้ลบแบบเรียกซ้ำ นี่อาจจะซนมาก และ +1 สำหรับไวยากรณ์เฉพาะ makefile
Daishi

หาก rm -rf อาจเป็น "naughty" หมายความว่าคุณกำลังใช้ make นอกไดเรกทอรีภายใต้การควบคุมเวอร์ชัน ทำไม?
Godsmith

กรุณาให้ลิงค์ไปยังเอกสารโปรด ไม่พบคำอธิบายของคุณลักษณะนี้
George Sovetov


14

หากคุณไม่ต้องการใช้ตัวเลือก -f ทางเลือกคือ:

rm filethatdoesntexist 2> /dev/null 

นี่จะเป็นการป้องกันข้อผิดพลาดจากการพิมพ์


9
น่าเสียดายที่นี่ยังคงให้รหัสข้อผิดพลาดในการออก
Shaun McDonald

8

หากคุณพบว่าวิธีการบางglobชื่อไฟล์ที่rmจะไม่บ่นถ้ามันไม่สามารถพบการแข่งขัน ดังนั้นสิ่งที่ชอบlexer.m* interpparse.*ฯลฯ ควรเหมาะกับคุณ (ระวังว่าคุณจะไม่ลบมากเกินไป) นอกจากนี้ยัง-fเป็นวิธีการที่เหมาะสมอย่างสมบูรณ์แบบตราบใดที่คุณไม่ได้หวังว่าการอนุญาตให้ใช้ไฟล์จะช่วยให้คุณไม่ต้องลบไฟล์ที่คุณไม่ต้องการ - หากคุณไม่ต้องการลบไฟล์อย่าใส่มัน ในรายการ


The globbing จะออกจากคำถามเนื่องจากมีไฟล์ lexer.mll ที่ฉันไม่ต้องการลบ ขอบคุณที่แสดงว่าทำไม -f จึงสมเหตุสมผล sudo rm -rfฉันคิดว่าฉันมีแนวโน้มที่จะต้องระมัดระวังมากเกินไปหลังจากที่หนึ่งมากเกินไปเข้าใจผิด
เจสันเบเกอร์

ไม่เข้มงวดมากขึ้นlexer.m?... ? ที่จะจับlexer.mlและlexer.mzแต่ไม่ได้หรือlexer.mll lexer.mla
JMD

1
@JMD: ฉันคิดว่ามันขึ้นอยู่กับเปลือกของคุณและสิ่งที่สนับสนุนการจับคู่รูปแบบที่มีให้สำหรับ globbing
Nick Bastin

6

อ็อพชัน -f หมายความว่าคุณจะไม่ได้รับพร้อมต์หากบางสิ่งไม่เป็นไปตามที่คาดไว้ ไม่ได้หมายความว่าสิทธิ์จะไม่นำมาพิจารณา

หากคุณมีสิทธิ์ไม่เพียงพอที่จะลบไฟล์ไฟล์นั้นจะไม่ถูกลบ

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


5

อาจช่วยให้คล้ายกับ:

touch fakefile.exe fakefile.o && rm *.o *.exe

ฉันรู้ว่านี่ไม่ใช่สมาร์ทมาก แต่ทำงานได้


3

ทางเลือก:

RmIfIsFile() {  for f in "$@"; do [ -f $f ] && rm $f; done; };  RmIfIsFile lexer.ml interpparse.ml interpparse.mli

Makefiles ที่แย่เกินไปไม่สามารถแบ่งปันนิยามฟังก์ชันเชลล์ข้ามบรรทัดได้


คุณได้ลองใช้ \ (แบ็กสแลช) ที่ท้ายแถวเพื่อให้มันดำเนินต่อไปในครั้งต่อไปหรือไม่?
บาง

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

3

นี่คือสิ่งที่ฉันใช้ในเชลล์สคริปต์ มันซ่อนข้อความข้อผิดพลาดและรหัสข้อผิดพลาด

rm doesnotexist 2> /dev/null || echo > /dev/null

วิธีการเกี่ยวกับrm doesnotexist 2&> /dev/null
user8162

1

คุณสามารถสัมผัสไฟล์ก่อนที่จะ rm พวกเขา ที่จะสร้างพวกเขาหากพวกเขาไม่อยู่ :-)

touch lexer.ml interpparse.ml interpparse.mli
rm lexer.ml interpparse.ml interpparse.mli

1

เขียนrm -rf ppp>/dev/null 2>&1 คุณใหม่รับข้อความแสดงข้อผิดพลาดปัญหาเกิดขึ้นหากข้อผิดพลาดสร้างไม่ให้ STDERR 2 แต่ STDOUT 1 ... มันเกิดขึ้นเมื่อคำสั่งสร้างไม่ใช่ข้อผิดพลาด แต่คำเตือน คุณต้องตั้งค่าตัวกรองและลบข้อความนี้ แต่กรณีนี้เป็นเรื่องปกติ


1

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

if [ -f lexer.ml ]; then
  rm lexer.ml
fi

เพิ่มส่วนคำสั่งทดสอบเพิ่มเติมหากมีไฟล์มากขึ้นที่คุณต้องการให้แน่ใจว่ามีอยู่

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