сценарий оболочки для удаления файла, если он уже существует


184

Я работаю над некоторыми вещами, где я храню данные в файле. Но каждый раз, когда я запускаю скрипт, он добавляется к предыдущему файлу.

Я хочу помочь, как я могу удалить файл, если он уже существует.


3
Проверьте, существует ли файл ... и затем позвоните rm $my_file, верно? Какую оболочку вы используете?
Крис Спрэг,

Ответы:


185

Не пытайтесь проверить, существует ли файл, просто попробуйте удалить его.

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, но делать это совершенно бессмысленно. Вполне возможно, что тест вернет true, но / p / a / t / h не будет существовать до того, как вы попытаетесь удалить его, или, что еще хуже, тест не пройдёт и будет создан / p / a / t / h. перед выполнением следующей команды, которая ожидает, что она не существует. Попытка это классическое состояние гонки. Не делай этого.


5
Это не полезно, если им нужно знать, существует ли он и был ли он удален. Еда stderr не обеспечивает этого. Отсутствие обработки существования не позволяет запустить более широкий скрипт без сбоев.
Учуугака

@uchuugaka Это простое решение , если вы не заботитесь , если файл существует, все , что вы хотите, чтобы убедиться сделать это не существует.
Лукас Лиезис

Хорошие ответы должны быть получены и полны о побочных эффектах - это обобщение моего сообщения, но сценарии оболочки часто хотят знать, что найдено или не найдено, а что есть или нет.
Учуугака

rm /p/a/t/h 2> /dev/nullне будет сохранять код возврата ( echo $?) как 0, если файл не существует. Это может привести к сбою заданий в Jenkins только потому, что мы попытались удалить несуществующий файл.
ViFI

@uchuugaka - Я довольно долго не отвечал на этот комментарий, но его нужно решить. Проверка, существует ли файл перед удалением, всегда плохая идея. Смотрите последний абзац моего ответа. Существует неотъемлемое состояние расы, которого просто невозможно избежать, совершая подобные вещи. Если вы не хотите перезаписывать существующий файл, вы можете попробовать какую-то особую магию для оболочки (например, noclobberв bash) или, возможно, изменить существующий файл, чтобы выполнить перенаправление, если файл существует (не избегает условия гонки), но все, что нужно сделать, это сделать ошибки более тонкими.
Уильям Перселл

128

Еще одна однострочная команда, которую я использовал:

[ -e file ] && rm file

11
Или альтернативно: [! -e файл] || рм файл. Эта версия возвращает 0 вместо некоторой ошибки.
Nawfel BGH

@nawfelbgh Спасибо, это отлично подходит для цепочки в длинном скрипте.
Абэ

84

Вы можете использовать это:

#!/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он не выдаст ошибку. Этот ответ помог мне, спасибо.
Даг

Согласитесь с Дагом, хотя это похоже на хороший вариант использования вики-подобного редактирования ответа.
Филипп

16

Сценарий оболочки с одним вкладышем для удаления файла, если он уже существует (основываясь на ответе Джиндры Хелкл):

[ -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 

-f проверяет, является ли это обычный файл

-e проверяет, существует ли файл

Введение в если для получения дополнительной информации

РЕДАКТИРОВАТЬ: -e используется с -f излишним, fo использование только -f тоже должно работать


-aустарела, используйте -eвместо.
mziccard

мой плохой, исправленный. Спасибо @mziccard
P1kachu

это приведет к ошибкам в каталогах или ссылках или других нестандартных файлах. Имхо лучше / безопаснее в использовании -f.
Джиндра Хелкл

1
хорошо. тем не менее, -ein -feявляется избыточным, так как -fтакже проверяет наличие файла, насколько я знаю ..
Jindra Helcl

Если я отредактирую, я просто сделаю дубликат из вашего ответа, но я
уточню

4

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

Кроме того, если вы перенаправите вывод с помощью >вместо >>него, будет перезаписан предыдущий файл


3
это не одна строка, извините, но @liwp_Stephen один это.
fiorentinoing

Даже если правильно цитировать, это ломается, если fileчто-то вроде5 -lt 2
Уильям Перселл
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.