Existe uma maneira de saber se um arquivo é copiado?

2

O cenário é o seguinte: A Máquina A tem arquivos que eu quero copiar para a Máquina C. A Máquina A não pode acessar diretamente o C, mas pode acessar a Máquina B que pode acessar a Máquina C. Estou usando o scp para copiar da Máquina A para B e depois de B para C.

A máquina B tem espaço de armazenamento limitado, assim como os arquivos entram, eu preciso copiá-los para C e excluí-los de B. A segunda cópia é muito mais rápida, então isso não é problema com a largura de banda.

Eu poderia fazer isso manualmente, mas sou preguiçoso. O que eu gostaria é de executar um script em B ou C que irá copiar cada arquivo para C como cada um termina . O trabalho scp está sendo executado de A.

Então, o que eu preciso é uma maneira de perguntar (de preferência de um script bash) se o arquivo X.avi é "feito" copiando. Cada um desses arquivos tem um tamanho diferente e não posso prever o tamanho nem o tempo de conclusão.

Editar: a propósito, os tempos de transferência de arquivos são de aproximadamente 1 hora de A para B e cerca de 10 minutos de B para C, se a escala de tempo for importante.

    
por Mike Cooper 22.09.2009 / 19:37

6 respostas

4

Uma maneira comum de fazer isso é primeiro copiá-lo para um nome de arquivo temporário, preferencialmente um arquivo oculto. Quando a cópia termina, o script que está fazendo a cópia renomeia o nome do arquivo não oculto.

O script na máquina B pode, então, procurar por arquivos não ocultos.

O script na máquina A seria parecido com isto:

for file in 'ls *' ; do
    scp $file user@host:~/.${file}.tmp
    ssh user@host "mv ~/.${file}.tmp $file"
done

Embora isso não satisfaça o desejo do OP de usar a linha one

scp * user@host:~/

realiza a mesma coisa e também permite que a máquina B transfira cada arquivo à medida que termina sem esperar pelo próximo arquivo.

    
por 22.09.2009 / 20:00
2

O lsof na máquina B mostra que o scp tem o arquivo aberto? Se assim for, você pode assistir lsof e ver quando scp fecha o arquivo. Se não, você pode ver o tamanho do arquivo e depois que ele não for alterado por um determinado período de tempo (5 minutos, por exemplo), copie-o de B para C.

Uma terceira opção seria copiar os arquivos de A para um diretório "in_progress" em C. Depois que a cópia terminar em A, execute o comando mv para sair do diretório "in_progress".

    
por 22.09.2009 / 19:53
2

Acabei de pensar em outra opção completamente diferente. Não usa scp em tudo. Por favor, deixe-me saber se isso funcionaria:

  1. em B, crie um pipe fifo em algum lugar: mkfifo / tmp / xfer

  2. em A, não use scp, em vez disso, tar -cz files | ssh B 'cat > /tmp/xfer

  3. em C, execute ssh B 'cat /tmp/xfer' | tar -xz

Dessa forma, os dados não são armazenados em B, apenas passam pelo pipe. A desvantagem disso é que você só pode ter uma cópia por vez ...

Você precisará garantir que o processo em C seja reproduzido a cada vez que terminar.

    
por 22.09.2009 / 21:10
2

Depois de pensar sobre as respostas postadas (em particular a idéia do @ Josh de assistir os tempos modificados) eu estava tentando manipular os arquivos de B em C. Veja, B é anêmico quanto às ferramentas disponíveis, então nada que pareça ser capaz de fazer o trabalho estava lá. Eu encontrei essa solução. Esta ideia não é minha, encontrei-a nas pesquisas do Google antes desta questão. Eu descartei isso antes, já que a máquina B não tinha o utilitário find .

Primeiro, monte o diretório apropriado em B em C, para que ele apareça como um sistema de arquivos local. Eu usei sshfs para isso (ferramenta incrível, por sinal). Isso me permitirá usar os utilitários do C ao invés do B's.

Em segundo lugar, o comando find /the/folder/* -mmin +5 corresponderá a todos os arquivos modificados há mais de 5 minutos. Portanto, o comando find /the/folder/* -mmin +5 -exec {} /the/other/folder \; moverá todos os arquivos que foram modificados há mais de 5 minutos para a outra pasta (que é na verdade em C, em vez de sshfs montados em B.

Por fim, configurei um script cron para executar o script acima a cada 10 minutos hoje e amanhã. A linha no meu crontab se parece com isso.

*/5 * 22,23 9 * find /the/folder/* -mmin +5 -exec mv {} /the/other/folder \;

Espero que isso funcione. O próximo arquivo ainda não foi concluído, então não posso comentar se ele realmente funciona quando combinado com o script cron, mas fiz alguns arquivos manualmente e os semeei e eles se moveram bem. cruze meus dedos

Editar: Isso está funcionando, embora como ele originalmente teve alguns erros, eles foram corrigidos agora.

    
por 22.09.2009 / 21:29
1

Não há necessidade de mkfifo. Na máquina B, execute isto:

ssh A 'tar -cz files' | ssh C 'tar -xz'

Você pode achar útil a opção -C do tar.

Se você precisar iniciar a cópia na máquina A, faça o seguinte:

tar -cz files' | ssh B "ssh C 'tar -xz'"

Cuidado com as citações adequadas.

    
por 01.06.2010 / 12:22
0

A cópia será executada como um outro processo ou você poderá forçá-la a usar um subshell. Então, você poderia usar ps para "assistir" o processo e ver quando ele desaparece.

Além disso, acredito que no * nix, você pode excluir o arquivo enquanto ele está sendo copiado. O sistema não irá apagá-lo até que o programa de cópia o feche. Claro, se a cópia não for bem sucedida, você perde o arquivo, então não é a melhor idéia.

    
por 22.09.2009 / 20:34

Tags