shell script para remover um arquivo, se ele já existir

183

Estou trabalhando em algumas coisas em que estou armazenando dados em um arquivo. Mas cada vez que executo o script, ele é anexado ao arquivo anterior.

Quero ajuda sobre como remover o arquivo, se ele já existir.

Niks
fonte
3
Verifique se o arquivo existe ... e ligue rm $my_file, certo? Qual shell você está usando?
22815 Chris Sprague

Respostas:

184

Não se preocupe em verificar se o arquivo existe, tente removê-lo.

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

Observe que o segundo comando falhará (retornará um status de saída diferente de zero) se o arquivo não existir, mas o primeiro será bem-sucedido devido à opção -f(abreviação de --force). Dependendo da situação, esse pode ser um detalhe importante.

Mas o mais provável é que, se você estiver anexando ao arquivo, é porque seu script está usando >>para redirecionar algo para o arquivo. Apenas substitua >>por >. É difícil dizer, pois você não forneceu nenhum código.

Observe que você pode fazer algo assim test -f /p/a/t/h && rm /p/a/t/h, mas fazê-lo é completamente inútil. É bem possível que o teste retorne verdadeiro, mas o / p / a / t / h deixará de existir antes de tentar removê-lo, ou pior, o teste falhará e o / p / a / t / h será criado antes de executar o próximo comando que espera que ele não exista. Tentar fazer isso é uma condição clássica de corrida. Não faça isso.

William Pursell
fonte
5
Isso não é útil se eles precisarem saber se existia e foi excluído. Comer stderr não fornece isso. Não lidar com a existência não permite que você execute um script mais amplo sem falhar.
Uchuugaka
@uchuugaka Esta é uma solução simples quando você não se importa se existe um arquivo, tudo o que você quer é garantir que ele não esteja lá.
Lukas Liesis
Boas respostas devem estar próximas e completas sobre os efeitos colaterais é a generalização da minha mensagem, mas os scripts de shell freqüentemente querem saber o que é ou não encontrado e o que é ou não acionado.
uchuugaka 27/01/19
rm /p/a/t/h 2> /dev/nullnão manterá o código de retorno ( echo $?) como 0 se o arquivo não existir. Isso faria com que os trabalhos de Jenkins falhassem apenas porque tentamos excluir um arquivo inexistente.
ViFI 30/05/19
@uchuugaka - Evitei responder a esse comentário há algum tempo, mas ele precisa ser resolvido. Verificar se o arquivo existe antes de excluí-lo é sempre uma má ideia. Veja o parágrafo final da minha resposta. Existe uma condição de raça inerente que simplesmente não pode ser evitada fazendo esse tipo de coisa. Se você não deseja sobrescrever um arquivo existente, tente alguma mágica específica do shell (como noclobberno bash) ou talvez modifique o arquivo existente para que o redirecionamento falhe se o arquivo existir (não evita a condição de corrida), mas tudo o que fará é tornar os bugs mais sutis.
William Pursell 30/06
127

Outro comando de uma linha que usei é:

[ -e file ] && rm file
liwp_Stephen
fonte
11
Ou alternativamente: [ ! arquivo -e] || arquivo rm. Esta versão retorna 0 em vez de algum erro.
Nawfel bgh
@nawfelbgh Obrigado, isso é ótimo para encadear em um script mais longo.
Abe
83

Você pode usar isto:

#!/bin/bash

file="file_you_want_to_delete"

if [ -f $file ] ; then
    rm $file
fi
Jindra Helcl
fonte
4
Essa deve ser a resposta selecionada.
ingernet
Simples e fácil de ler e também garante que echo $?não dê 1 se o arquivo não existir.
ViFI 30/05/19
Se necessário, você também pode fazer isso como uma linha, veja minha resposta abaixo.
N
65

Se você deseja ignorar a etapa para verificar se o arquivo existe ou não, é possível usar um comando bastante fácil, que excluirá o arquivo se existir e não emitirá um erro se ele não existir.

 rm -f xyz.csv
greperror
fonte
1
Esta é apenas uma duplicata da parte da resposta mais bem classificada, de 2015.
forgivenson
16
a resposta principal não explicava que, com o -fargumento, não haveria erro. Esta resposta me ajudou, obrigado.
Doug
Concorde com Doug, embora esse pareça um bom caso de uso para uma edição de resposta de wiki.
Philip
16

Um script shell de um liner para remover um arquivo, se ele já existir (com base na resposta de Jindra Helcl):

[ -f file ] && rm file

ou com uma variável:

#!/bin/bash

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

Algo assim funcionaria

#!/bin/sh

if [ -fe FILE ]
then 
    rm FILE
fi 

-f verifica se é um arquivo comum

-e verifica se o arquivo existe

Introdução ao if para obter mais informações

EDIT: -e usado com -f é redundante, fo usando -f sozinho deve funcionar também

P1kachu
fonte
-aestá obsoleto, use em -evez disso.
Mziccard
meu mal, fixo. Obrigado @mziccard
P1kachu
isso gerará erros em diretórios ou links ou outros arquivos não normais. É melhor / mais seguro de usar -f.
Jindra Helcl
1
Está bem. Ainda assim, o -eem -feé redundante, como -ftambém verifica a existência do arquivo, tanto quanto eu sei ..
Jindra Helcl
Se eu editar, vou apenas fazer uma fora duplicado da sua resposta, mas eu vou preciso ele
P1kachu
4

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

Além disso, se você redirecionar sua saída com, em >vez >>dela, substituirá o arquivo anterior

nLee
fonte
3
este não é um one-liner, desculpe, mas o @liwp_Stephen é esse.
Fiorentinoing
Mesmo se citado corretamente, isso interrompe se fileé algo como5 -lt 2
William Pursell