여러 디렉토리를 동시에 ftp하는 Ksh 스크립트

여러 디렉토리를 동시에 ftp하는 Ksh 스크립트

저는 이 사이트를 처음 사용하는데 다음과 같은 문제가 발생했습니다.

내부에 여러 디렉터리가 있는 유닉스 디렉터리가 있습니다. 각 디렉터리에는 약 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.
$

보시다시피 그 중 하나만 완료되었습니다(코드 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

귀하의 루프가 스크립트 끝에서 작동하지 않는 것 같습니다. 하나의 변수, 즉 에서 많은 쌍을 수집합니다 a. awk에 의해 인쇄된 줄 바꿈은 쉘에 의해 공백으로 변환되기 때문에 이러한 모든 쌍은 공백으로 구분됩니다. 그런 다음 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

관련 정보