strtok을 사용하다가 1번만 자른 뒤 나머지가 필요한 경우가 생겼다.
그래서 뒤적이다 보니 strsep라는 또다른 분리 함수를 찾았다. 하지만 이걸로도 해결은 불가능 했다.
원했던 만큼만 분리 후 나머지를 취할 수는 있었지만 strtok과는 다르게 구분자로 된 문자열을 통째로 분리하지 못했다. 이전에 포스팅 했던 strtok 샘플과 비교해보면 눈에 띄는 차이를 알 수 있다.
샘플은 이전 strtok 때 썼던 것을 재사용했다.

#include <STRING.H>  
int main( ) 
{ 
    char* token = NULL; 
    char* str = NULL;
    char str1[] = " ! This is\tStrtok,Test Program!!!! end\n"; 
    char  str2[] = " ,\t\n!"; 

    str = strdup( str1 );
    token = strsep( &str, str2 ); 
    while( token != NULL ) 
    { 
        printf( "token = %s", token ); 
        putchar( '\n' ); 
        token = strsep( &str, str2 ); 
    } 

    printf("검색이 완료된 원본 문자열 : %s\n",str1); 
    str = strdup( str1 );
    token = strsep( &str, str2 ); 
    printf( "token = %s", token ); 
    printf( "seped = %s", str ); 

  
    return 0; 
}

문자열을 소문자 혹은 대문자로 일괄 변환하고 싶을 때 아래와 같이 썼다.

    for( j=0;j<( int )strlen( aComStr->tok[i] );j++ )
    {
        if( aComStr->tok[i][j] >= 'A' && aComStr->tok[i][j] <= 'Z' )
        {
            aComStr->tok[i][j] +=32;
        }
    }

하지만 이미 제공되는 함수가 있었다....아래는 그 예제이다.

#include <string.h>

int main()
{
    char str[1024];
    strcpy( str, "Hello World 1234");
    int i;

    printf("before : %s\n", str);
    for (i=0; i< (int)strlen(str); i++)
    {
        str[i]=toupper(str[i]);
    }
    printf("after1 : %s\n", str);
    for (i=0; i< (int)strlen(str); i++)
    {
        str[i]=tolower(str[i]);
    }
    printf("after2 : %s\n", str);
}

회사 svn이 워낙 중요한 데이터가 있다보니 백업의 중요도가 상당하다...
그래서 매일 백업을 해 특정 저장 공간에 보관하려고 하는데 쓰려고 간단하게 쉘을 하나 작성하였다.
대단한건 아니고 svn 저장소를 통째로 압축하여 전달하는 역할이다. 이 쉘 스크립트는 이전 회사에서 부터 써오던 쉘스크립트를 내가 맘데로 변형 발전시켜온 것인데...토대가 되는 쉘 스크립트의 저작권은 아마도 전 회사에 귀속되어있을테니 이거 가지고 '너 고소!' 하면 할말은 없을지도....
설마 그정도로 쓰래기 짓을 하겠냐 하는 분도 있겠지만 지금 하는 행태로 봐선 쓰래기들이 쓰래기짓하고 있음.

#!/bin/sh
# 변수 등록
_DATE=`date '+%Y%m%d'`
_LOG_TIME=`date '+[%Y/%m/%d %H:%M:%S]'`
_EX_DAY=2
_BACKUP_DIR=$HOME/BACKUP
_LOG_DIR=$_BACKUP_DIR
_BACKUP_FILE=svn_backup
_LOGFILE=$_LOG_DIR/svn_backup.log


_LOGGING()
{
    echo "[`date '+%Y/%m/%d %H:%M:%S'`] $*"  >> $_LOGFILE
}

if [ ! -d $_BACKUP_DIR -a ! -x $_BACKUP_DIR ]
then
    echo "mkdir $_BACKUP_DIR"
    mkdir $_BACKUP_DIR
    if [ $? -ne 0 ]
    then
        echo "Error : mkdir $_BACKUP_DIR" >&2
        exit 1;
    fi
fi

if [ ! -d $_LOG_DIR -a ! -x $_LOG_DIR ]
then
    echo "mkdir $_LOG_DIR" 
    mkdir $_LOG_DIR
    if [ $? -ne 0 ]
    then
        echo "Error : mkdir $_LOG_DIR" >&2
        exit 1;
    fi
fi

# 기간이 만료된 백업 삭제
find $_BACKUP_DIR -type f -name "${_BACKUP_FILE}_*" -mtime +$_EX_DAY -exec rm -f {} \;

# 백업 시작
_LOGGING "SVN BACKUP START!"

killall svnserve >> $_LOGFILE 2>&1
if [ $? -eq 0 ]
then
    _LOGGING "SVN SERVICE STOP SUCCESS!"
else
    _LOGGING "WARNING! SVN SERVICE NOT RUNNING."
    #exit 1;
fi

ps -ef | grep -v grep | grep "svnserve -d" >> $_LOGFILE 2>&1
if [ ! $? -eq 1 ]
then
    _LOGGING "WARNING! DETECT SVNSERVE PROCESS."
    #exit 1;
fi

#tar -cf - $HOME/svnrepo | gzip -c - > ${_BACKUP_DIR}/${_BACKUP_FILE}_${_DATE}.tar.gz
if [ $? -eq 0 ]
then
    _LOGGING "SVN BACKUP SUCCESS!"
else
    _LOGGING "WARNING! SOME PROBLEM IN BACKUP JOB."
    exit 1;
fi

_LOGGING "SEND TO REPOSITORY!"
scp ${_BACKUP_DIR}/${_BACKUP_FILE}_${_DATE}.tar.gz  svn@dev2:~/BACKUP/.
if [ $? -eq 0 ]
then
    _LOGGING "SEND SUCCESS!"
else
    _LOGGING "WARNING! FAIL TO SEND BACKUP."
    #exit 1;
fi

svnserve -d -r /home/svn/svnrepo
if [ $? -eq 0 ]
then
    _LOGGING "SVN SERVICE START SUCCESS!"
else
    _LOGGING "WARNING! FAIL TO START SVN SERVICE."
    #exit 1;
fi
_LOGGING "SVN BACKUP END!"

저장소 장비에서는 특정 기간이 만료된 백업을 제거하는 쉘을 수행해야 한다.

_EX_DAY=7
_BACKUP_DIR=$HOME/BACKUP
_BACKUP_FILE=svn_backup

# 일주일이 지난 백업 삭제
find $_BACKUP_DIR -type f -name "${_BACKUP_FILE}_*" -mtime +$_EX_DAY -exec rm -f {} \;

이제 crontab에 등록해보자. crontab에 최빈시에 백업이 수행되도록 등록만 하면 된다. 사내 장비는 아직 특별한 것이 없으므로 임의로 새벽 1시에 수행되게 설정하였다.

0 1 * * * ~/BACKUP/svn_backup.sh