FTP granel download e renomear

2

Primeiro de tudo: por que estou tentando isso? Porque precisamos baixar alguns arquivos E renomear para encurtar aqueles com data "selos". Os arquivos remotos têm nomes de arquivos realmente enormes e não é uma opção para mudar (não é nosso ftp).

Eu estou tentando fazer um download em massa e renomear alguns arquivos em um servidor ftp remoto, sem ter que abrir uma conexão ftp para cada arquivo que eu tenho que baixar. Até agora, eu poderia conseguir renomear e baixar on-the-fly com nmap ftp comando, renomeando todos os arquivos que começa com "N" e termina com ".TXT" para "N_date_time_stamp.TXT"

ftp -niv $url << FTP_COMMAND
        user $user $password
        cd $remotedir
        nmap N*.TXT N_'date "+%H%M%N"'.TXT
        mget N*
        bye
FTP_COMMAND

O problema é: nmap mantém o mesmo valor% N para todos os arquivos passados para o mget, e deve mudar em cada download para o valor atual de nanossegundos:

250 CWD command successful.
local: N_1054232349627.TXT remote: NO2346662345257245624572457245724562411125555341346134771345123461146-44.TXT
227 Entering Passive Mode (xxxxxxxxxxxxxxx).
125 Data connection already open; Transfer starting.
226 Transfer complete.
2220 bytes received in 0,0995 secs (22 Kbytes/sec)
local: N_1054232349627.TXT remote: NO2346662345257245624572457245724562411125555341346134771345123461146-45.TXT
227 Entering Passive Mode (xxxxxxxxxxxxxx).
125 Data connection already open; Transfer starting.
226 Transfer complete.
2220 bytes received in 0,107 secs (20 Kbytes/sec)

Existe uma maneira de atualizar o nmap em cada download?

    
por nwildner 29.08.2013 / 16:11

4 respostas

2

Bem, eu fiz algum tipo de implementação mista, baseada nas respostas de Stephane e slm. Eu não poderia usar zsh porque é um servidor de produção e instalar um novo shell não é uma opção, então eu usei o lftp que foi instalado:

Explicação : No primeiro here_docs ( FTPLISTGET ), conecte-se ao servidor ftp e liste os arquivos ( nlist ). Se a listagem foi bem-sucedida ( if [ $? -eq 0 ] ), um arquivo por renomeação com a data atual no formato ano, mês, dia, hora, minuto, nanossegundo. Alguns ftps estão em alta velocidade, e salvar o segundo pode sobrescrever os arquivos.

exec_ftp(){

# LIST
LIST_FTP='lftp $protocol://$url << FTPLISTGET
        user $user $pass
        nlist
        bye
FTPLISTGET'

# Check if list is not empty, proceed...
if [ $? -eq 0 ]; then
        echo "$LIST_FTP" | while read file
        do
                DEST="N_$(date +%Y%m%d%H%M%N).TXT"
                lftp $protocol://$url <<-DOWNLOAD
                        user $user $pass
                        cd $remotedir
                        get $file -o /home/user/$DEST
                        rm $file
                        bye
                DOWNLOAD
        echo "Done in $(date +%d/%m/%Y-%T)" >> /var/log/transfer_ftp.log
        done

# If listing is not possible, 
else
        echo "FTP: $url user: $user - Cant reach host, or wrong credentials" >> /var/log/transfer_ftp_error.log
fi

}

Editar 1 : Alterou os backticks para $(...) , como sugerido por slm, e adicionou a variável $protocol . Por quê? Porque lftp pode baixar e automatizar sftp e ftps, e isso será muito bom para nós:)

    
por 29.08.2013 / 21:28
3

com zsh :

autoload zfinit
zfinit
zmodload zsh/datetime

files=N*.TXT
zfopen $host $user $passwd &&
  zfcd $remotedir &&
  zfrglob files &&
  for f ($files) {
    t=$EPOCHREALTIME
    strftime -s ts %H%M%S ${t%.*}
    ts=$ts.${t#*.}
    zfgcp -Gt $f N_$ts.TXT
  }
zfclose
    
por 29.08.2013 / 17:21
3

ftp não me parece a ferramenta apropriada para fazer isso. Eu tentaria lftp em vez disso. Como você escreveu a linha:

    nmap N*.TXT N_'date "+%H%M%N"'.TXT

O Get é avaliado uma vez e depois expandido para a data atual. A partir de então, ele só será usado como o formulário expandido. O que você quer fazer é obter o lado remoto para fazer essa expansão para você, o que eu não acredito que você possa fazer com o FTP regular.

Algo parecido com isto "pode" funcionar em lftp :

$ lftp -u user,password IP <<EOF
!whoami
quit 0
EOF

Eu não tenho acesso a um servidor FTP atualmente, então não posso testar isso. Se funcionar, você poderá modificá-lo para que o comando date seja executado no servidor remoto.

Referências

por 29.08.2013 / 16:53
2

A maneira mais fácil de fazer coisas complexas com o FTP é não lidar com o FTP. Monte o recurso de FTP como um sistema de arquivos. O FUSE está amplamente disponível hoje em dia, mesmo em servidores com configurações de software restritas. Você pode usar Curlftpfs para montar diretórios FTP.

mkdir /net/someftp.example.com
curlftpfs -o user=bob someftp.example.com /net/someftp.example.com

Armazene a senha de FTP em ~/.netrc .

Em seguida, use os comandos normais do shell para copiar os arquivos com os nomes desejados. Eu não recomendo este esquema de microssegundos, já que você depende da atualização do clock rápido o suficiente, o que pode ser problemático, especialmente se o relógio for ajustado enquanto o script é executado. Use um contador em vez disso.

counter=10000
date=$(date +%Y%m%d-%H%M%S)
for x in /net/someftp.example.com/dir/N*.txt; do
  cp -p "$x" "N-$date-${counter#1}.TXT"
  counter=$((counter+1))
done

Quando você terminar o diretório FTP, desmonte-o com fusermount -u /net/someftp.example.com .

    
por 30.08.2013 / 00:31