Ksh 脚本同时 ftp 多个目录

Ksh 脚本同时 ftp 多个目录

我是这个网站的新手,我遇到了这个问题:

我在unix中有一个目录,里面有多个目录。每个目录大约有 5k 个文件。所以我们谈论的是 40k 到 50k 的文件。我需要使用 FTP 将其发送到 Windows 服务器(只是因为我只有 FTP)。所以,我有一个脚本,循环遍历每个目录并发送这些文件。然而,这是痛苦的缓慢过程,所以我想同时进行。这就是我现在所拥有的,它开始发送这些文件,然后不知何故永远不会完成。日志仅显示它最终正在处理 221 消息。但是,这并不能保证我的所有文件都已发送。我对它们进行手动计数,发现有时当一个文件夹有 5000 个文件时,有时只会发送 800 个文件。日志没有指明方向。

此外,我的脚本在传输停止后仍继续运行很长时间。我可以使用 ps -ef 看到它。

有人可以看一下并提出任何改进建议,或者为什么我会出现这种奇怪的行为?

有关我的设置的一些信息:

  • HP-UX 9000/859 B.10.20 E
  • 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 在运行一小时内就死掉了,也许是超时了?

-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

在我看来,你的循环在脚本末尾不起作用。您在一个变量中收集了许多对,即a。所有这些对都用空格分隔,因为 awk 打印的所有换行符都会被 shell 转换为空格。然后你echo只通过一行打印它。然后你用一个变量读回它,即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

除此之外,使用并行传输而不是串行传输可能不会按预期加速您的过程,因为您是通过同一条线路传输数据。此外,您还需要打开许多套接字而不是只打开一个套接字。

最后注意:我建议您使用不同的日志文件,否则来自不同 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

相关内容