Ksh Script para ftp vários diretórios simultaneamente

2

Sou novo neste site e tenho este problema:

Eu tenho um diretório no unix com vários diretórios nele. Cada diretório tem cerca de 5k arquivos nele. Então estamos falando de arquivos de 40k a 50k. Eu preciso enviar isso para um servidor windows, usando FTP (só porque eu só tenho FTP). Então, eu tenho um script que, faz um loop através de cada diretório e enviou esses arquivos. No entanto, isso é doloroso lento, então eu quero fazê-lo simultaneamente. Isto é o que eu tenho agora, ele começa a enviar esses arquivos e, em seguida, de alguma forma nunca termina. Log apenas mostrar que estava trabalhando com uma mensagem 221 no final. No entanto, isso não garante que todos os meus arquivos sejam enviados. Eu faço uma contagem manual sobre eles e posso ver que, às vezes, quando uma pasta tem 5000 arquivos, por vezes, apenas 800 são enviados. Log não mostra o caminho.

Além disso, meu script continua funcionando muito depois que a transferência é interrompida. eu posso ver isso usando ps -ef.

Alguém pode dar uma olhada e aconselhar qualquer melhoria ou por que estou tendo esse comportamento estranho?

Algumas informações sobre minha configuração:

  • HP-UX 9000/859 B.10.20 E
  • Versão do Ksh: como? tentou --version, echo $ KSH_VERSION, swlist, nada funcionou

Meu script:

#! /usr/bin/ksh

if [[ $# -eq 0 ]]; then
  print "No arguments, Please enter password for ftp process"
  exit
fi

exec 4>~/ftpParallel.log

#Directory to send
CONVERTED_DIR=/data/history/
#FTP Variables
HOST=xxxxx.com
PORT=8009
USER=yyyyy
PASS=$1

ftpFiles(){
    #   Do some processing and lets get the group and the dategroup, Format will be#    /DATA/BRCPCB/201101
    GROUP=$1
    DATEGROUP=$2
    #now mount the destdir based on the curent dir
    DESTDIR=/DATA/$GROUP
    cd $CONVERTED_DIR/$GROUP/$DATEGROUP
    i=0
    ftp -nv >&4 2>&4 |&
    print -p open $HOST $PORT
    print -p user $USER $PASS
    print -p mkdir $DESTDIR
    print -p mkdir $DESTDIR/$DATEGROUP
    print -p cd $DESTDIR/$DATEGROUP
    ls | while read filename ; do
      [[ -f $filename ]] && print -p put $filename
      (( i += 1 ))
    done
    print -p close
    print -p bye
    print -p "$DATEGROUP send $i files"
}

#Get All Folders structure, we will need it to iterate and search for PeakPro Files Later
a='find $CONVERTED_DIR -type d  2>/dev/null | awk 'BEGIN{FS="/"}{if($NF ~/^[0-9]{6}$/)print $(NF-1),$NF}'' 
echo "$a" | while read item ; do
   ftpFiles $item & #this will make the function be called in background
done
wait
exit 0

UPDATE :

Eu mudei o código conforme solicitado e encontrei novas coisas interessantes. Parece que meus trabalhos de FTP continuam funcionando, mesmo depois que eles pararam: Estes são os logs de FTP:

$ tail -5 ftpParallel200103.log
150 Opening ASCII mode data connection for C31905.CVFS.
226 Transfer complete.
15931 bytes sent in 0.01 seconds (2117.55 Kbytes/s)
200 PORT command successful.
150 Opening ASCII mode data connection for C31905.RVFS.
$ tail -5 ftpParallel200104.log
200 PORT command successful.
150 Opening ASCII mode data connection for WG4829.RVFS.
226 Transfer complete.
12110 bytes sent in 0.01 seconds (1011.91 Kbytes/s)
221  
$ tail -5 ftpParallel200105.log
150 Opening ASCII mode data connection for C51047.CVFS.
226 Transfer complete.
159734 bytes sent in 0.15 seconds (1027.98 Kbytes/s)
200 PORT command successful.
150 Opening ASCII mode data connection for C51047.RVFS.
$

Como você pode ver, apenas 1 deles terminou (Código 221 - FTP BYE). Outros nunca terminaram e o trabalho continua em execução (comecei usando nohup ftpParallel.sh & ):

 rcsanto  8314  8299  5 10:15:27 ttyq6     0:00 ps -ef
 rcsanto 25834 25833  0 05:35:00 ?         0:00 ls
 rcsanto 25828 25826  0 05:35:00 ?         0:00 ls
 rcsanto 25813 25808  0 05:35:00 ?         0:27 ftp -nv
 rcsanto 25815 25808  0 05:35:00 ?         0:19 ftp -nv
 rcsanto 25833 25816  0 05:35:00 ?         0:01 ftpParallel.sh ./ftpParallel.sh roJabSuP08WJjco
 rcsanto  8299  8298  0 10:15:15 ttyq6     0:00 -sh
 rcsanto  8315  8299  1 10:15:27 ttyq6     0:00 grep rcsanto
 rcsanto 25808     1  0 05:34:46 ?         0:00 ftpParallel.sh ./ftpParallel.sh roJabSuP08WJjco
 rcsanto 25826 25815  0 05:35:00 ?         0:02 ftpParallel.sh ./ftpParallel.sh roJabSuP08WJjco
 rcsanto 25816 25808  0 05:35:00 ?         0:08 ftp -nv
 rcsanto 25825 25813  0 05:35:00 ?         0:02 ftpParallel.sh ./ftpParallel.sh roJabSuP08WJjco
 rcsanto 25827 25825  0 05:35:00 ?         0:00 ls

Este é o LOG do nohup:

FTP starting at: Tue Feb  5 04:51:48 CST 2013        rm: /homrm: /homrm: /homrm: /homrm: /homrm: /home/rcsante/rcsante/rcsante/rcsante/rcsante/rcsanto/ftpParo/ftpParo/ftpParo/ftpParo/ft
    allel200allel200104.log non-existent
    107.log non-exi106.log304.log non-existent
     non-existent
     stent
     non-existent

Eu acredito que as variáveis estão sendo bagunçadas de alguma forma. TI também parece que o FTP morre dentro de uma hora de execução, talvez sua eliminação?

-rw-rw-rw-   1 rcsanto    pp_user     249853 Feb  5 05:51 ftpParallel200103.log
-rw-rw-rw-   1 rcsanto    pp_user     937693 Feb  5 06:22 ftpParallel200104.log
-rw-rw-rw-   1 rcsanto    pp_user     172395 Feb  5 05:47 ftpParallel200105.log
-rw-rw-rw-   1 rcsanto    pp_user      88497 Feb  5 05:41 ftpParallel200106.log
-rw-rw-rw-   1 rcsanto    pp_user     981598 Feb  5 06:24 ftpParallel200107.log
-rw-rw-rw-   1 rcsanto    pp_user     819814 Feb  5 06:21 ftpParallel200304.log

Obrigado por toda sua ajuda.

    
por Toze 31.01.2013 / 16:33

1 resposta

1

Parece-me que o seu loop, no final do script, não está funcionando. Você coleta um número de casais em uma variável, ou seja, a . Todos esses pares são separados por espaços porque todas as novas linhas impressas pelo awk são convertidas em espaços pelo shell. Então você imprime, via echo como apenas uma linha. E você lê de volta em uma variável, ou seja, item . Então item tem o mesmo conteúdo que a . Isso significa que seu loop só faz um loop uma vez. Se eu entendi o que você está fazendo, você pode mudar isso da seguinte maneira:

find $CONVERTED_DIR -type d 2>/dev/null \
  | awk 'BEGIN{FS="/"}{if($NF ~/^[0-9]{6}$/)print $(NF-1),$NF}'' \
  | while read group dategroup
do
  ftpFiles $group $dategroup & #this will make the function be called in background
done

Além disso, ter uma transferência paralela em vez de uma serial, provavelmente não acelerará seu procedimento como esperado, porque você está transferindo dados pelo mesmo fio. Além disso, você tem a sobrecarga de abrir muitos soquetes em vez de apenas um.

Última observação: sugiro que você tenha arquivos de log diferentes, porque senão todas as saídas de um ftp diferente serão misturadas.

update : A função interna provavelmente pode ser reescrita desta forma:

( echo open $HOST $PORT
  echo user $USER $PASS
  echo mkdir $DESTDIR
  echo mkdir $DESTDIR/$DATEGROUP
  echo cd $DESTDIR/$DATEGROUP
  ls | while read filename ; do
      [[ -f $filename ]] && echo put $filename
      (( i += 1 ))
    done
  echo close
  echo bye
  echo "$DATEGROUP send $i files" >&4 ) | ftp -nv >&4 2>&4
    
por 31.01.2013 / 19:13