2011-01-11 5 views
8

내가 그렙와 꼬리 로그 파일에 원하는과 같은 메일 을 통해 전송 :꼬리 그렙 로그 및 메일 (리눅스)

tail -f /var/log/foo.log | grep error | mail -s subject [email protected] 

내가 어떻게 할 수 있습니까?

+0

"나는'print ('Foo');와 같은 질문을하고 'Foo'를 출력하고 싶습니다. 어떻게해야합니까?" 귀하의 질문은 정확히 * 무엇입니까? –

+1

'tail' * -f *는 파일의 맨 아래를 계속해서 따라갈 것이므로 아마 원하지 않을 것입니다. 'grep'은 ** 꼬리 ** 로그도 아닙니다. 해결하려는 문제는 무엇입니까? – Johnsyweb

+0

'꼬리 - f .. | grep ...'은 파일이 커지면서 grep을 사용하여 추가 된 데이터를 출력하는 것인데, 단지 – ajreal

답변

2

나는 이것에 가야할 것이다. 아마 칙칙한 bash 코드가 자세히 조사되면 뭔가 배울 것입니다. 이미이 작업을 수행 할 수있는 해결책이 있지만, 당신이 사이버 오션의 깊이와 너비를 트롤 한 것으로 확신 할 수는 없습니다. 그것은 당신이 원하는 것처럼 들리 네 비트로 분리 될 수 있습니다 : 1) 정기적 인 간격으로 파일의 '최신 꼬리'를 얻습니다. 2) 최신 꼬리가 실제로 존재하면 전자 우편으로 보내십시오. 1)의 일정 간격 동안 cron을 사용하십시오. 2)에서 최신 꼬리를 얻으려면 파일 크기를 추적해야합니다. 아래의 bash 스크립트는 cron이 호출 할 수있는 2)의 해결책입니다. 캐시 된 파일 크기를 사용하여 메일에 필요한 파일의 청크를 계산합니다. myfile 파일의 경우 다른 파일 인 .offset.myfile이 작성됩니다. 또한 스크립트는 파일 이름에 경로 구성 요소를 허용하지 않습니다. 호출에서 다시 작성하거나 수정하십시오. (cd/foo/bar & & segtail.sh zut), 이것을 segtail.sh라고합니다.

#!/usr/local/bin/bash 
file=$1 
size=0 
offset=0 
if [[ $file =~/]]; then 
    echo "$0 does not accept path components in the file name" 2>&1 
    exit 1 
fi 
if [[ -e .offset.$file ]]; then 
    offset=$(<".offset.$file") 
    fi 
if [[ -e $file ]]; then 
    size=$(stat -c "%s" "$file") # this assumes GNU stat, possibly present as gstat. CHECK! 
            # (gstat can also be Ganglias Status tool - careful). 
fi 
if (($size < $offset)); then  # file might have been reduced in size 
    echo "reset offset to zero" 2>&1 
    offset=0 
fi 
echo $size > ".offset.$file" 
if [[ -e $file && $size -gt $offset ]]; then 
    tail -c +$(($offset+1)) "$file" | head -c $(($size - $offset)) | mail -s "tail $file" [email protected] 
fi 
+0

질문에 대한 grep 부분이 응답되지 않았습니다. 운동으로 남았습니다. – micans

+0

파일 이름 변수 확장에 대한 전체 인용 부호가 필요합니다. bash에 대한 경로가 모든 시스템에서 올바르지 않습니다. 어쩌면'env'를 통해 호출 할 수 있습니다. 'stat'의 출력은 시스템과 버전 (!) 사이에서 매우 가변적입니다. 최근의 GNU 통계를 가정 할 때, -c를 사용하여 이것을 분석하고 구문 분석의 필요성을 피하십시오. – Sorpigal

+0

'cat'은 필요 없습니다 :'offset = $ (<. offset. $ file)'. if [[-e $ file && $ size> $ offset]]'의 두 번째 부분은 어휘 비교이므로'$ size' == 10 및'$ offset '== 2. 대신 이것을 사용하십시오 :'[[-e $ file]] && (($ size> $ offset))'. '(())'와'$ (())'안에 대부분의 경우 달러 기호를 생략 할 수 있습니다. –

17

이메일로 오류가 발생하면 이메일을 보내시겠습니까? 은 grep 출력의 모든 라인 이메일을 보냅니다

tail -f $log | 
grep --line-buffered error | 
while read line 
do 
    echo "$line" | mail -s subject "$email" 
done 

: 당신은 그러나이 같은 시도 할 수

), 즉 실패 할 수 있습니다.

nohup ./monitor.sh & 

와 쉘 스크립트 위

실행 그래서 백그라운드에서 계속 실행됩니다.

+1

후행 백 슬래시가 필요하지 않습니다. 쉘은 후행 파이프 (또한'&','&&'및'||')에 대한 다음 행을 찾습니다. –

+0

흥미로운 ... 한 가지 놓친 것. 감사합니다 @glenn jackman –

+1

오류 후 10 줄을 출력하려고한다고 가정합니다 (grep -A 10 오류). 귀하의 접근 방식에서는 10 개의 전자 메일을 받게됩니다. 10 개의 전자 메일을 포함하여 하나의 전자 메일 만 수신하려면 어떻게해야합니까? – markus