เชลล์สคริปต์เพื่อลบไฟล์หากมีอยู่แล้ว


183

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

ฉันต้องการความช่วยเหลือเกี่ยวกับวิธีลบไฟล์ถ้ามีอยู่แล้ว


3
ตรวจสอบว่ามีไฟล์อยู่ ... แล้วโทรrm $my_fileใช่ไหม คุณใช้เปลือกอะไร
Chris Sprague

คำตอบ:


184

ไม่ต้องตรวจสอบว่ามีไฟล์อยู่หรือไม่ลองลบออก

rm -f /p/a/t/h
# or
rm /p/a/t/h 2> /dev/null

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

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

โปรดทราบว่าคุณสามารถทำสิ่งที่ชอบtest -f /p/a/t/h && rm /p/a/t/hแต่การทำเช่นนั้นไม่มีจุดหมายอย่างสมบูรณ์ มีความเป็นไปได้ค่อนข้างมากที่การทดสอบจะกลับเป็นจริง แต่ / p / a / t / h จะล้มเหลวก่อนที่คุณจะพยายามลบมันหรือแย่กว่านั้นการทดสอบจะล้มเหลวและ / p / a / t / h จะถูกสร้างขึ้น ก่อนที่คุณจะรันคำสั่งถัดไปซึ่งคาดว่าจะไม่มีอยู่ ความพยายามนี้เป็นเงื่อนไขการแข่งขันแบบคลาสสิก อย่าทำมัน


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

@uchuugaka นี่เป็นวิธีแก้ปัญหาง่ายๆเมื่อคุณไม่สนใจว่ามีไฟล์อยู่ที่นั่นทั้งหมดที่คุณต้องการคือทำให้แน่ใจว่าไม่มีไฟล์นั้นอยู่
Lukas Liesis

คำตอบที่ดีควรเตรียมพร้อมและสมบูรณ์เกี่ยวกับผลข้างเคียงคือลักษณะทั่วไปของข้อความของฉัน แต่เชลล์สคริปต์มักต้องการทราบว่าอะไรคืออะไรหรือไม่พบและอะไรคืออะไรหรือไม่ดำเนินการ
uchuugaka

rm /p/a/t/h 2> /dev/nullจะไม่เก็บรหัสส่งคืน ( echo $?) เป็น 0 หากไม่มีไฟล์อยู่ นั่นจะทำให้งานของเจนกินส์ล้มเหลวเพียงเพราะเราพยายามลบไฟล์ที่ไม่มีอยู่
ViFI

@uchuugaka - ฉันหลีกเลี่ยงการตอบความคิดเห็นนี้มาระยะหนึ่งแล้ว แต่จำเป็นต้องได้รับการแก้ไข ตรวจสอบว่าไฟล์ที่มีอยู่ก่อนที่จะลบมันเป็นเสมอความคิดที่ดี ดูย่อหน้าสุดท้ายของคำตอบของฉัน มีสภาพการแข่งขันโดยธรรมชาติที่ไม่สามารถหลีกเลี่ยงได้โดยการทำสิ่งนั้น หากคุณไม่ต้องการเขียนทับไฟล์ที่มีอยู่คุณสามารถลองใช้เวทย์มนตร์เฉพาะเชลล์ (เช่นnoclobberใน bash) หรืออาจจะเปลี่ยนไฟล์ที่ยังหลงเหลืออยู่ดังนั้นการเปลี่ยนเส้นทางล้มเหลวหากไฟล์นั้นมีอยู่ (ไม่หลีกเลี่ยงสภาพการแข่งขัน) แต่สิ่งที่จะทำคือทำให้แมลงมีความละเอียดยิ่งขึ้น
William Pursell

127

อีกหนึ่งบรรทัดคำสั่งที่ฉันใช้คือ:

[ -e file ] && rm file

11
หรืออีกทางหนึ่ง: [! ไฟล์ -e] || ไฟล์ rm รุ่นนี้ส่งคืน 0 แทนข้อผิดพลาดบางอย่าง
nawfel bgh

@nawfelbgh ขอบคุณนี่เป็นสิ่งที่ยอดเยี่ยมสำหรับการผูกมัดในสคริปต์ที่ยาวขึ้น
Abe

83

คุณสามารถใช้สิ่งนี้:

#!/bin/bash

file="file_you_want_to_delete"

if [ -f $file ] ; then
    rm $file
fi

4
นี่ควรเป็นคำตอบที่เลือก
ingernet

ง่ายและอ่านง่ายและยังรับประกันว่าecho $?จะไม่ให้ 1 หากไม่มีไฟล์
ViFI

หากจำเป็นคุณสามารถทำสิ่งนี้เป็นแบบซับไลน์ดูคำตอบของฉันด้านล่าง
nbeuchat

65

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

 rm -f xyz.csv

1
นี่เป็นเพียงส่วนหนึ่งของคำตอบที่ได้รับการจัดอันดับสูงสุดตั้งแต่ปี 2015
Forgivenson

16
คำตอบหลักไม่ได้อธิบายว่า-fมันจะไม่ผิดพลาด คำตอบนี้ช่วยฉันขอบคุณ
Doug

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

16

ซับเชลล์สคริปต์หนึ่งสคริปต์เพื่อลบไฟล์หากมีอยู่แล้ว (ขึ้นอยู่กับคำตอบของ Jindra Helcl):

[ -f file ] && rm file

หรือด้วยตัวแปร:

#!/bin/bash

file="/path/to/file.ext"
[ -f $file ] && rm $file

13

บางสิ่งเช่นนี้จะได้ผล

#!/bin/sh

if [ -fe FILE ]
then 
    rm FILE
fi 

- ตรวจสอบว่ามันเป็นไฟล์ปกติหรือไม่

-e ตรวจสอบว่ามีไฟล์อยู่หรือไม่

รู้เบื้องต้นเกี่ยวกับถ้าสำหรับข้อมูลเพิ่มเติม

แก้ไข: -ใช้กับ -f ซ้ำซ้อนหากใช้ -f เพียงอย่างเดียวก็ควรทำงานเช่นกัน


-aเลิกใช้แล้วใช้-eแทน
mziccard

ฉันไม่ดีคงที่ ขอบคุณ @mziccard
P1kachu

การทำเช่นนี้จะทำให้เกิดข้อผิดพลาดในไดเรกทอรีหรือลิงก์หรือไฟล์อื่นที่ไม่ใช่ปกติ มันเป็น IMHO ดีกว่า / -fปลอดภัยในการใช้งาน
Jindra Helcl

1
ตกลง. ยังคงที่-eใน-feซ้ำซ้อนขณะที่-fยังมีการตรวจสอบการดำรงอยู่ของไฟล์เท่าที่ผมทราบ ..
Jindra Helcl

ถ้าฉันแก้ไขฉันจะทำซ้ำคำตอบของคุณ แต่ฉันจะแม่นยำ
P1kachu

4

if [ $( ls <file> ) ]; then rm <file>; fi

นอกจากนี้หากคุณเปลี่ยนเส้นทางเอาต์พุตของคุณด้วย>แทนที่จะ>>เป็นการเขียนทับไฟล์ก่อนหน้า


3
นี่ไม่ใช่สายการบินขออภัย แต่ @liwp_Stephen อันนี้ก็เป็นเช่นนั้น
fiorentinoing

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