複数のディレクトリを同時にftpするKshスクリプト

複数のディレクトリを同時にftpするKshスクリプト

私はこのサイトを初めて使用していましたが、次の問題が発生しました。

内部に複数のディレクトリがあるUnixディレクトリがあります。各ディレクトリには約5,000個のファイルがあります。したがって、私たちは約40,000〜50,000のファイルについて話しています。 Windowsサーバーに送信するにはFTPを使用する必要があります(FTPのみがあるため)。したがって、各ディレクトリを繰り返してこれらのファイルを送信するスクリプトがあります。しかし、これは痛いほど遅いプロセスなので、両方を同時に実行したいと思います。これが私が今持っているものです。ファイルの送信を開始し、何とか完了しません。ログには、最終的に221メッセージが処理されていることだけが表示されます。しかし、これは私のすべてのファイルが転送されたことを保証するわけではありません。手動で計算してみると、フォルダに5000個のファイルがあるとき、時には800個のファイルだけが転送されることもありました。ログは方向を表しません。

また、私のスクリプトは転送が停止した後も長時間実行され続けます。 ps -efを使って見ることができます。

誰かを見て改善を提案できますか?それとも、なぜこのような奇妙な動作が発生するのですか?

私の設定に関するいくつかの情報:

  • HP-UX 9000/859 B.10.20E
  • Kshバージョン:どうですか? --version、echo $KSH_VERSION、swlistを試しましたが、何も機能しません。

私のスクリプト:

#! /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

修正する:

リクエストに応じてコードを変更し、新しい興味深いコンテンツを見つけました。 FTP ジョブが停止した後も実行を続けているようです。 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.
$

ご覧のとおり、そのうちの1つのみが完了しました(コード221 - FTP BYE)。他のジョブは完了せず、ジョブは引き続き実行されます(私はを使用して開始しました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

これは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

私は変数が何らかの形で混乱したと思います。また、FTPが実行後1時間以内に終了したことを示します。タイムアウトした可能性がありますか?

-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

助けてくれてありがとう。

ベストアンサー1

あなたのループがスクリプトの最後で動作しないようです。 1つの変数、つまりから多くのペアを収集しますa。 awkによって印刷された改行はシェルによってスペースに変換されるため、これらのペアはすべてスペースで区切られます。その後、echo1行だけ印刷してください。その後、変数を使用して再読み込みします。つまり、item同じitem内容を持ちますa。これは、ループが一度だけ繰り返されることを意味します。やっていることを理解したら、次のように変更できます。

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

さらに、シリアル転送の代わりに並列転送を使用すると、同じワイヤを介してデータを転送するため、プロセス速度が期待どおりに向上しない可能性があります。また、1つではなく多くのソケットを開く必要があります。

最後の注意:別のログファイルを使用することをお勧めします。それ以外の場合は、他のFTPのすべての出力が一緒に混在します。

修正する:内部関数は次のように書き直すことができます。

( 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

おすすめ記事