InfraPlatform

[Bash Shell-Script 기초 다지기] - Rsync를 이용한 디렉토리 복사-복제

IT오이시이 2014. 3. 7. 13:53
728x90

[Bash Shell-Script 기초 다지기] - Rsync를 이용한 디렉토리를 복사-복제(rsync사용)

 

셀스크립트는 주로 반복적이면서도 빠르게 작성해서 실행하여야 하고  가독성이 빨라야 합니다.  그래서 되도록 복잡한 로직 보다는 기능 단위로 단순화하고 간단하면서 명료하게 작성을 해야 합니다.
이번에는 디렉토리를 복사하거나 이동하는 데 주로 사용할 예제로 작성을 해 보았습니다.

 

[디렉토리 관리를 위한 유용한 명령어]

셀스크립트로 디렉토리를 관리하기 위해서는  1) 디렉토리의 유무,  2) 디렉토리 경로 등을 처리할 수 있어야 한다.

 주로 많이 사용하는 명령어 두가지를 정리하면 아래 와 같습니다.

1. 파일 생성시 존재 여부 확인하기 


 -  if 를 이용한 디렉토리 가 존재하는지 판단하기

  if [ -d "dir_name" ]    : 디렉토리가 있는지 확인합니다. 

  ※      -d : 디렉토리   , -e : 존재 유무  , -x : 실행 가능    -L   : file Link 여부 등

 

mkdir -p  "$dir_name"    : mkdir 은 하부 디렉토리를 만들지 않습니다.

    - 깊이가 2단계 이상인 디렉토리를 만들 경우 디렉토리의 생성을 확실히 하기 위해서는
      -p   옵션으로 하부 디렉토리(sub directory)가 없더라도 여러 단계 깊이의 하부 디렉토리를  한번에 생성할 수 있습니다.



 예시1)  디렉토리 유무를 확인하고 처리하기

 

 dirname="/data/home/test1"    
if [ -d "$dirname" ]     
then
          ls -al ${dirname}
else
          mkdir -p  ${dirname}
fi

 

2.  dirname 과 basename : 현재 디렉토리 Path명과 파일 명을 구분 하자 

 dirname 과 basename 는 

 

    - 디렉토리 또는 파일의 full-path, full-name을 처리하는 방법으로 "dirname" 과  "basename"을 활용한다.   

basename 은 파일 path 중에서  파일명 또는 마지막 depth 디렉토리명을 추출합니다.

[사용법]  basename
#>  basename  "some_path_name"   :  맨뒤의 파일 이름이나 디렉토리 명 1개를  나타낸다.


[예시]
#> basename "logs/php/20110321.log.gz "
     20110321.log.gz

#> basename "logs/php/20110321"
     20110321

 

dirname 은 파일 path 중에서 디렉토리 명을 추출합니다.
     *  dirname 은  입력된 path에서 파일 이름을 제외하고 디렉토리 이름을 나타낸다.

[사용법]  dirname

#>  dirname    "logs/php/20110321.log.gz" 
           logs/php

 

3. 디렉토리명들을 변수 리스트(List변수)로 만들어 반복문 처리 하기

  

 여러개의 디렉토리를 한꺼번에 관리하기 위해서는 반복 처리가 필요합니다.
 반복 처리를 위해서    vlists="Var1  Var2  Var3" 와 같이  space로 구분된 문자열로  List 로 만들수 있습니다.
 반복문은 주로 for 문장으로 아래와 같이 Loop를 수행 할 수 있습니다.

 

  dir_lists="/data/dname1  /data/dname2 /data/dname3 ".

    for  var in $dir_lists
   do

          반복 수행될 문장..
   done

 

 

 

[디렉토리 관리를 위한 스크립트 작성하기]

 # 아래 조건으로 스크립트를 작성하여 보자

  1) /data/아래 특정 디렉토리 이름을 변수로 입력받아  /ndata/data/ 아래로 복제 하는 스크립트를 작성한다.

  2) 하부 디렉토리가 없으면 디렉토리를 만든다.

  3) 파일 복사는 "rsync"  명령으로 복제한다.

 

  1. 복사항 디렉토리 들을 변수로 만들어 보자 

     SVC_DIRS="/data/CVSHOME /data/DATABASE /data/GITHOME"

 

   2. 디렉토리를 검사하고 디렉 토리가 없으면 생성하는 함수를 아래와 같이 만든다.

       * mkdir -p "dir_name"  으로 하부 디렉토리를 생성한다.

       * [$?]   : 마지막 수행된 명령의 결과로 0 은 성공    0 이외의 값은 실패를 나타낸다.

 

    function fn_Chkdir () {

        if [ !  -d "$1" ]

        then

            mkdir -p $1

            echo " fn_Chkdir : mkdir $1 [$?] "

        else

            echo " fn_Chkdir [ok] "

        fi

    }

 

   3. 디렉토리 리스트를 반복하여  파일 복사를 수행 하는 문장을 구현 한다.

    for v_dir in $DATA_DIRS

    do

        v_dname=`dirname "$v_dir" | sed -e "s/^/\/ndata/"`

        fn_Chkdir  $v_dname

        echo " rsync -ar --progress $vdir /ndata/data "     

    done

 

    * dirname  :  dirname Variable  에서  파일명을 제외한 디렉토리명을 출력함

    * sed       : 문자열 스트림을 입력 받아 문자열 치환을 할 수 있다.

    *   v_dname=`dirname "$v_dir" | sed -e "s/^/\/ndata/"` 는 디렉토리 이름을  ndata로 변경한다.

         :  /data/CVSHOME   는 /ndata/CVSHOME  로 변경 된다.

    *  rsync -ar --progress $vdir /ndata/data  는  복사를 진행하는 상태를  화면에 출력한다.

 

전체 스크립트를 정리하면 아래와 같다.

 

    ###    function Section ####    

    function fn_Chkdir () {

        if [ !  -d "$1" ]

        then

            mkdir -p $1

            echo " fn_Chkdir : mkdir $1 [$?] "

        else

            echo " fn_Chkdir [ok] "

        fi

    }

    ###    Main  Section ####

    DATA_DIRS="/data/CVSHOME /data/DATABASE /data/GITHOME"

    for v_dir in $DATA_DIRS

    do

        v_dname=`dirname "$v_dir" | sed -e "s/^/\/ndata/"`

        fn_Chkdir  $v_dname

        echo " rsync -ar --progress $vdir /ndata/data "     

    done

728x90
반응형