2010-03-02 11 views
7

bash-fu 마법사 용입니다. 아니, 사실, 농담이야, 나를 제외하고는이 모든 것을 잘 알고있을거야 ..Bash 스크립팅, 오류 점검, 로깅

백업 셸 스크립트를 만들려고합니다. 아이디어는 매우 간단합니다. 특정 폴더에서 7 일 이상 된 파일을 찾아 다른 디렉토리로 tar/gzip하고 제거합니다. 문제는 대상 디렉토리에 tar/gzip 파일을 만들 수있는 권한이 있는지 확실하지 않습니다. 파일이 성공적으로 만들어 졌는지 확인하는 방법이 있습니까? 그렇다면 파일을 삭제하십시오. 그렇지 않으면 해당 부분을 건너 뛰고 고객 데이터를 파괴하지 마십시오. 나는 그들이 그 것을별로 좋아하지 않는다고 들었다. 여기

내가 지금까지 가지고 무엇 : 기본적으로

01: #!/bin/bash 
02: 
03: ROOTDIR="/data/www" 
04: 
05: TAR="${ROOTDIR}/log/svg_out_xml/export_out_ack_$(date +%Y-%m-%d).tar" 
06: cd ${ROOTDIR}/exchange/export/out_ack/ 
07: find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}" 
08: gzip ${TAR} 
09: find . -mtime +7 -type f -print0 | xargs -0 rm -f 

, 그래서 또한 9

를 실행하면 나는 '모든 것이 선 7, 8에 잘 갔다 있는지 확인해야하고, 줄 d는 이러한 작업에 대한 로그 파일을 만들고 싶기 때문에 모든 것이 잘되었다는 것을 알았습니다 (이것은 야간에 cron 작업입니다).

+1

모든 코멘트를 올리십시오. 사전에 만들어진 안전 장치를 사용하십시오. – Recursion

+0

경험에서 말하면 재귀? :) –

+0

당신의 꼬리표는 "bash"라고하지만, 당신의 꼬마는 "sh"라고 말합니다. –

답변

6

로그를 들어, 중괄호 스크립트의 섹션을 포장 할 수 있으며 로그 파일에 표준 출력을 리디렉션 :

{ 
    script_command_1 
    script_command_2 
    script_command_3 
} >> /path/to/log_file 
+0

Kewl, 다음과 같이 작성하면 작동합니다. $$ {LOG} 2> & 1' –

+0

@dr : 예, 가능합니다. –

5

밖으로 쉬운 방법,하지만 명시 적 오류 메시지 즉, 오두막에 명령이 실패하면 쉘이 종료하게됩니다 #!/bin/sh -e-e를 추가 ..

크론은 메일을 통해 오류 메시지를 제공한다 나는 생각한다.

만약 당신이 완전히 날려 버린 백업 계획에 가고 싶다면, 나는 당신이 이미 만들어진 것을 사용할 것을 제안합니다. 무리가 있고 대부분 잘 작동합니다.

+0

우수 제안. 나는 항상 스크립트에서'-e'를 사용한다. –

+0

팁 주셔서 감사합니다, 매우 유용합니다! 불행하게도 cron은 우리가이 시스템의 관리자가 아니기 때문에 아무 것도 보내지 않을 것입니다. .. –

+0

@dr : 당신이 crontab에 MAILTO를 정의한다면 그것은 가능할 것입니다. – falstro

3

GNU tar에는 --remove-files이 있습니다.이 파일은 일단 아카이브에 추가되면 파일을 제거합니다. v은 파일을 추가 할 때 파일을 나열합니다. z은 gzip을 통해 tar를 즉시 파이프합니다.

귀하의 find 해결책은 확실합니다. 파일은 호출 사이에 기준에 맞을 수 있으므로 삭제되지만 백업되지는 않습니다.

+0

답변 해 주셔서 감사합니다. 백업 할 폴더에 파일을 만들지 않을 때이 스크립트는 4AM에서 실행되므로 파일이 호출간에 적합하지는 않습니다. 물론, 항상 한 명의 사용자가 있습니다. –

11

로그를 들어, 표준 출력 및/또는 표준에 기록 된 모든 출력을 주선 할 수 있습니다 오류로 인해 파일로 이동하십시오. 그런 식으로, 당신은 각 명령의 출력을 리디렉션 할 필요가 없습니다 : 이전 하나의 성공에만

# Save standard output and standard error 
exec 3>&1 4>&2 
# Redirect standard output to a log file 
exec 1>/tmp/stdout.log 
# Redirect standard error to a log file 
exec 2>/tmp/stderr.log 

# Now the output of all commands goes to the log files 
echo "This goes to /tmp/stdout.log" 
echo "This goes to /tmp/stderr.log" 1>&2 
... 

# Print a message to the original standard output (e.g. terminal) 
echo "This goes to the original stdout" 1>&3 

# Restore original stdout/stderr 
exec 1>&3 2>&4 
# Close the unused descriptors 
exec 3>&- 4>&- 

# Now the output of all commands goes to the original standard output & error 
... 

이 명령을 실행하기를, 당신은 조건문으로 그들을 체인 수 : 그래서 당신은

# Execute command2 only if command1 succeeds, and command3 only if both succeed: 
command1 && command2 && command3 

# Execute command2 only if command1 fails 
command1 || command2 

find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}" || 
    { echo "find failed!!" 1>&2; exit 1 } 
gzip ${TAR} || 
    { echo "gzip failed!!" 1>&2; exit 1 } 
find . -mtime +7 -type f -print0 | xargs -0 rm -f || 
    { echo "cleanup failed!!" 1>&2; exit 1} 
: 로그 출력

{ find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}" && 
    gzip ${TAR} && 
    find . -mtime +7 -type f -print0 | xargs -0 rm -f } || 
    { echo "Something failed" 1>&2; exit 1 } 

또는 제공 사항 등의 작업을 수행 할 수 있습니다

+0

+1, 굉장한 정보! –

+0

'1>'은'>' –

+3

에 암시되어 있지만 1>은 더 명확합니다. – Idelic