Posts Tagged 'Shellscript'

Backup script

1. gplBackup.sh

이 스크립트는 실수로 rm * 또는 rm –rf * 등의 명령을 내려 작업중인 source code를 삭제했을 때 복구할 수 있도록 파일들을 주기적으로 backup하는 스크립트입니다. 이 스크립트와 cron 명령을 함께 사용하게 되는데, 사용하기 위한 설정 과정은 다음과 같습니다.

1) 위의 스크립트를 Backup하고자 하는 디렉토리들이 있는 가장 상위의 디렉토리에 복사합니다.

예를 들어, /home/userid/codes/modeling과 /home/userid/codes/inversion 두 개의 디렉토리를 backup하고 싶을 때 위 스크립트를 다음의 디렉토리에 복사합니다.

/home/userid/codes/gplBackup.sh

2) 스크립트를 수정하여 backup하고자 하는 디렉토리와 확장자, backup에서 제외하고자 하는 디렉토리를 설정합니다.

Backup할 디렉토리는 dirList라는 배열에 저장합니다. Backup은 recursive하게 수행되기 때문에 subdirectory들 중 제외하고 싶은 디렉토리가 있을 경우, excDirList에 제외하고 싶은 디렉토리명을 써줍니다. Backup은 확장자나 파일명을 기준으로 하게 됩니다. Backup하고 싶은 확장자나 파일명을 extList라는 배열에 적어줍니다. 마지막으로 backupdir 이라는 변수에 backup한 파일들이 들어갈 디렉토리명을 적어주면 기본적인 스크립트 수정이 끝나게 됩니다.

예> backupdir = “/home/userid/codes/backup”

여기 적은 디렉토리는 미리 만들어 놓도록 합니다.

3) crontab -e로 crontab 파일 연 다음 아래의 줄을 추가합니다.

10 * * * * /home/userid/codes/gplBackup.sh

위의 6개의 항목이 의미하는 바는 다음과 같습니다.

분, 시, 일, 달, 요일, 실행 명령

따라서 위의 명령은 매 달, 매 일, 매 시 10분에 backup 스크립트를 실행하라는 명령입니다. 위의 줄을 추가한 후에는 crontab -l로 위의 줄이 추가되었는지 확인할 수 있습니다. 여기까지 해 놓으면 설정이 끝납니다.

위의 스크립트는 매 시 10분에 해당 디렉토리의 해당 파일들을 backup하고 스크립트 40번째 줄에 지정된 시간이 되면 디스크 용량 절약을 위해 지금까지 backup했던 파일들을 삭제합니다. 매일 지정된 시간에 생성된 파일은 남겨둡니다. 지정된 시간에 생성된 파일은 이름이 다릅니다. 기본적으로 매 시간 생성되는 파일은 “backup20090307-1210.tgz” 와 같은 이름을 가지고, 지정된 시간에 생성되는 파일은 “Backup.20090307-1510.tgz”와 같은 이름을 가집니다.

주의사항) 위 스크립트는 rm *과 같은 상황에 대비하기 위해 만든 것이기 때문에 되도록이면 주로 작업하는 code들만 backup하도록 하세요. 현재 컴퓨터에 있는 source code를 전부 backup하고 싶은 경우에는 아래의 gplFullBackup 스크립트를 사용합시다.

또, 공용 서버를 사용하는 경우, 위의 10분이라고 나온 예에서 10분을 27분, 38분과 같이 다른 사람들이 안 쓸 것 같은 시간으로 바꾸세요. 모두가 같은 시간에 backup하도록 한다면 그 시간에 컴퓨터에 많은 부하가 걸리겠죠.

2. gplFullBackup.sh

이 스크립트는 위의 스크립트와 유사한데, 매 시간 실행되는 것이 아니라 사용자가 직접 실행하도록 만든 스크립트입니다. 실행하면 “./backup/FullBackup20090226-1536.tgz” 과 같은 파일을 만들어줍니다.

Iterative execution script

리눅스에서 동일한 작업을 이름 끝에 숫자가 붙은 여러 파일에 대해 반복적으로 하고 싶을 때 사용할 수 있는 shell script입니다.

#!/bin/bash
# Iterative execution script for numbered files
# http://plusha.com, 24 Mar 2007
#
# Procedure:
#   1. Modify variables - EXE, OPT, IN, OUT, NMIN, NMAX
#   2. Modify NUM format
#   3. Modify Input/Output type
#   4. Run the script
### put no space after '='

EXE=transp      # Execution file
OPT='n1=381'    # Options

IN=seismogram.          # basename of input files
OUT=trseismogram.       # basename of output files

NMIN=11         # Minimum number
NMAX=391        # Maximum number
INC=10          # Number increment

for (( i=$NMIN ; i<= $NMAX ; i=i+$INC ))
do
### NUM format
#  NUM=$( printf "%02d\n" $i )  # 01,10,...,99
NUM=$( printf "%03d\n" $i )  # 001,010,...,999
#  NUM=$( printf "%04d\n" $i )  # 0001,0010,...,9999
echo $NUM

### Input/Output type
#  $EXE $OPT   $IN$NUM   $OUT$NUM
$EXE $OPT < $IN$NUM > $OUT$NUM
#  $EXE $OPT < $IN$NUM
done

위의 내용을 그대로 실행하면 아래의 내용을 실행한 것과 같습니다.
transp n1=381 trseismogram.011
transp n1=381 trseismogram.021
...
transp n1=381 trseismogram.391

변수들을 바꿔서 다양하게 사용할 수 있겠죠. 만약 여러 파일들의 이름을 바꾸고 싶다면 어떻게 하면 될까요?
실행 명령을 mv로 바꾸고 옵션을 비우고 Input/output type을 첫 번 째 것으로 바꾸면 되겠죠? 그러면
mv old.001 new.001
mv old.002 new.002
mv old.003 new.003
...

과 같이 실행할 수 있겠죠. 하지만, 더 좋은 방법이 있습니다. ‘rename’ 명령을 사용하면 됩니다.
rename old new pattern
을 실행하면 세번째 argument의 pattern(glob pattern)에 해당하는 파일들을 모두 찾아 old라는 문자열을 new라는 문자열로 바꿔줍니다. 위의 경우에는
rename old new old.*
과 같이 실행할 수 있겠죠.

Recursive touch script

touch는 recursive 하게 실행되지 않아서 불편한 경우가 있습니다.
아래 shell script를 Rtouch.sh 라고 저장하고(물론 줄 번호는 제외 – vi에서 간단하게 제거할 수 있죠)
Rtouch.sh directory
라고 실행하면 directory 내에 있는 subdirectory와 file들을 touch 해줍니다.
15번째 줄의 find와 xargs를 이용하면 touch 뿐 아니라 다른 작업도 응용해서 할 수 있습니다.

01: #!/bin/sh
02: # Recursive Touch: touch files in a directory recursively
03: #
04: if [ $# -lt 1 ]
05: then
06:   echo "  Recursive Touch: touch files in a directory\
         recursively"
07:   echo "  Usage:"
08:   echo "          $0 [directory]"
09:   echo "  Required parameter:"
10:   echo "          directory name"
11:   exit 1
12: fi
13:
14: echo "touching $1"
15: find $1 -print0 | xargs -r0 touch
16: echo "files in $1 touched!"

xargs를 알기 전, 예전에는 다음과 같은 script를 만들어서 썼었죠.

01: #!/bin/sh
02: # touch files in a directory recursively03: #
04: cd directory
05: find > tmp11
06: sed 's#\(.*\)#touch\ \1#' < tmp11 > tmp22
07: sh tmp22
08: rm tmp11 tmp22
09: echo 'directory touched!'



팔로우

Get every new post delivered to your Inbox.

Join 39 other followers