Sintaxe para o comando rm. Preocupado com o uso da opção -r

0

Estou tentando criar uma rotina para gerenciar os arquivos de backup que estou criando, para que as pastas mais antigas sejam excluídas automaticamente no processo. Veja o que eu tenho:

#!/bin/sh
day=$(date +%m%d%y)
oldday=$(date -d "-4 days" +%m%d%y)
mkdir /home/fauna/backup/$day
rm -r /home/fauna/backup/$oldday
cp /home/fauna/backup/backup.sh /home/fauna/backup/$day
cd /home/fauna/backup/$day
./backup.sh

backup.sh realmente faz a criação dos arquivos de backup e copia a pasta com esses arquivos para um local remoto.

Essa linha rm excluirá essa pasta antiga sem nenhuma conseqüência não intencional?

Posso movê-lo para depois da linha backup.sh ?

    
por Rich Z 17.03.2016 / 07:40

2 respostas

3

Adicionar um cheque é uma boa ideia:

if [[ -d ~/backup/$oldday ]]; then
  rm -rf "$HOME/backup/$oldday"
fi

Além disso, usar aspas simples ou duplas corretamente no bash é importante. Especialmente os nomes de diretórios com espaços neles podem causar problemas quando não estão usando aspas.

Atualização: Estou supondo que o OP queira usar o bash.

    
por 17.03.2016 / 07:49
2

Você tem alguns problemas com a prática de codificação em seu código.

  1. Você gostaria de verificar o sucesso desses comandos, especialmente quando o próximo comando depender do sucesso do anterior.
  2. Deixar uma variável sem aspas no contexto de lista é pedir ao shell para dividi-lo e executar a geração de nome de arquivo nele, não há motivo para fazer isso aqui.

Agora, sobre rm -r , é necessário excluir o diretório e todo o seu conteúdo. Ele não seguirá links simbólicos ao fazer isso. Mesmo que /home/fauna/backup/$oldday seja um link simbólico, apenas esse link simbólico será removido. Isso é provavelmente o que você quer aqui. Seria diferente se você fizesse rm -r "/home/fauna/backup/$oldday/" (com o / ).

No entanto, sem -f , isso significa que, se stdin for um terminal, você poderá ser solicitado a remover arquivos não graváveis. Então, se é para ser um script autônomo, você provavelmente deve adicioná-lo. Também com -f , rm reporta falha se o diretório ainda estiver lá depois.

#!/bin/sh -
day=$(date +%m%d%y) || exit
oldday=$(date -d "-4 days" +%m%d%y) || exit
# date is very unlikely to fail, but if it does, it would have dramatic consequences

# shouldn't access to those directories be restricted (if it hasn't been
# restricted already some levels above)?
# umask 077

mkdir -p "/home/fauna/backup/$day" || exit
# with -p, mkdir would only fail if the directory is not there after that call.
# It may not be what you want though. You may want mkdir to fail if the
# directory already existed in which case you'd want to omit the -p.

cp /home/fauna/backup/backup.sh "/home/fauna/backup/$day" || exit

cd "/home/fauna/backup/$day" || exit
./backup.sh || exit

# only delete the old one if the new one succeeds.
rm -rf "/home/fauna/backup/$oldday"

Observe que, como estamos adicionando || exit a todos os comandos, podemos usar também set -e , o que faz com que o shell seja encerrado após qualquer erro de qualquer comando, mas eu prefiro || exit , como explicito que você considerou o tratamento de erros (e set -e tem muitas dicas para serem usadas de forma confiável (não neste caso simples aqui)).

    
por 17.03.2016 / 10:32

Tags