move arquivos de um dispositivo para outro

2

Estou tentando automatizar um backup remoto em nosso servidor centOS, eu executo o comando atual:

nice -n 10 mv -vfb /media/localbackup/* /media/remotebackup/

no entanto, quando isso é executado, recebo o seguinte erro e nenhum arquivo é movido

mv: inter-device move failed: '/media/localbackup/04-21-13' to '/media/remotebackup/04-21-13'; unable to remove target: Is a directory

Foi-me dito que é melhor usar o cp, mas isso não excluirá os arquivos depois e eu preciso remover os arquivos após um backup bem-sucedido.

    
por Neo 26.04.2013 / 10:45

4 respostas

4

Também sugiro que você use rsync em vez de mv , mas adicione à resposta do @ Hartmut :

rsync -abmv --remove-source-files /media/localbackup /media/remotebackup/
find /media/localbackup -depth -type d -empty -delete

E 2 adições aqui:

  1. O parâmetro -m ( --prune-empty-dirs ) para rsync , que na versão 3.0 do meu protocolo versão 3.0.7 diz: remove cadeias de diretórios vazias da lista de arquivos, mas não faz isso por algum motivo. Não erro ( não é o único a perceber isso ).
  2. O comando find , que excluirá os diretórios vazios.

agora, o motivo contra cp & & rm é que cp pode falhar a meio. A próxima vez que você quiser fazer o backup, você estará em uma situação estranha (arquivos parcialmente copiados para nomear o pior caso). Além disso, o próximo backup não saberá o que fazer com os arquivos anteriormente salvos em backup que não foram excluídos. Por outro lado rsync cobre esses aspectos bem.

Além disso, usar um script (como sugere a primeira resposta) para fazer o que o rsync já faz, mas pior, é um não-ir (desculpe Hauke Laging :-)). Não há necessidade de reinventar a roda aqui.

    
por 06.01.2014 / 13:25
2

Eu acho que muitas vezes quero fazer alguma operação em arquivos, preservando sua estrutura de diretórios. Por esse motivo, defini uma função bash filtercmd . Isso leva uma lista de arquivos para operar como stdin e como parâmetros executam a operação (por exemplo, mv ) e o diretório de destino. Depois de fazer isso, posso fazer coisas como um simples forro.

filtercmd () {
if [ ! -d "$2" ]; then echo "$2" does not appear to be a directory; return 1; fi
while read f; do
    dir="${f%/*}"
    if [ ! "$dir" = "$lastdir" ] 
        then mkdir -p "$2/$dir"; echo "$dir"; lastdir="$dir"; fi
    [ -e "$2/$f" ] || $1 "$f" "$2/$f"; done
}

(cd /media/localbackup && find . | filtercmd "mv -vfb" /media/remotebackup)

Isso também pode ser feito com rsync . Usar o protocolo remoto de rsync pode economizar muita largura de banda, pois o protocolo só precisa enviar blocos alterados. No entanto, duas vantagens de filtercmd over rsync são (1) que você pode usar seus sinalizadores mv existentes sem aprender os equivalentes de rsync e (2) e também podemos usar filtercmd para coisas mais poderosas como:

(z(){ grep . <$1|gzip >$2.gz;};find . -name '*.txt' | filtercmd z ../gz })

Que seleciona arquivos txt seletivamente, elimina linhas vazias e as compacta no diretório de destino.

    
por 02.04.2014 / 07:28
1

Seu comando tenta criar um diretório já existente. Você deve tornar este código de shell mais robusto:

tmpdirname=tmpdir
test -d "/media/remotebackup/${tmpdirname}" &&
  rm -rf "/media/remotebackup/${tmpdirname}"
pushd /media/localbackup/
test -d "$tmpdirname" && { echo Abbruch; exit 1; }
for dir in *; do
  test -d "/media/remotebackup/${dir}" && continue
  mv "$dir" "/media/remotebackup/${tmpdirname}" &&
    mv "/media/remotebackup/${tmpdirname}" "/media/remotebackup/${dir}"
done
popd

Isso irá pular diretórios que já foram movidos com sucesso.

    
por 26.04.2013 / 11:41
1

Eu usaria o comando rsync com a opção --remove-source-files.

Algo como rsync -abv --remove-source-files /media/localbackup/* /media/remotebackup/

Por favor, teste antes de aplicá-lo ao seu ambiente.

    
por 26.04.2013 / 13:13

Tags