태그 보관물: shell-script

shell-script

로그에 텍스트가 나타날 때 로그를 따르고 명령을 실행하는 가장 좋은 방법 있습니다. 서버가 가동되면 명령을 실행하고 싶으므로 다음과

서버가 작동 할 때 특정 텍스트 줄을 로그 파일에 출력하는 서버 로그가 있습니다. 서버가 가동되면 명령을 실행하고 싶으므로 다음과 같이하십시오.

tail -f /path/to/serverLog | grep "server is up" ...(now, e.g., wget on server)?

가장 좋은 방법은 무엇입니까?



답변

간단한 방법은 어색합니다.

tail -f /path/to/serverLog | awk '
                    /Printer is on fire!/ { system("shutdown -h now") }
                    /new USB high speed/  { system("echo \"New USB\" | mail admin") }'

그리고 둘 다 커널 로그의 실제 메시지입니다. Perl은 이것에 사용하기에 조금 더 우아 할 수도 있고 꼬리의 필요성을 대체 할 수도 있습니다. 펄을 사용한다면 다음과 같이 보일 것이다 :

open(my $fd, "<", "/path/to/serverLog") or die "Can't open log";
while(1) {
    if(eof $fd) {
        sleep 1;
        $fd->clearerr;
        next;
    }
    my $line = <$fd>;
    chomp($line);
    if($line =~ /Printer is on fire!/) {
        system("shutdown -h now");
    } elsif($line =~ /new USB high speed/) {
        system("echo \"New USB\" | mail admin");
    }
}

답변

당신은 단지 하나의 가능성을 찾고 사용하는 쉘에 주로 머물 것이 아니라 원하는 경우 awk또는 perl, 당신은 뭔가를 할 수 있습니다 :

tail -F /path/to/serverLog |
grep --line-buffered 'server is up' |
while read ; do my_command ; done

… 로그 파일에 my_commandserver is up “이 나타날 때마다 실행 됩니다 . 여러 가능성을 위해을 삭제하고을 grep대신 사용할 수 case있습니다 while.

수도 -Ftail로그 파일의 회전을 감시하도록 지시 합니다. , 현재 파일 이름이 바뀌고 동일한 이름을 가진 다른 파일이 대신 사용되면 tail새 파일로 전환됩니다.

--line-buffered옵션은 grep모든 줄마다 버퍼를 플러시하도록 지시 합니다. 그렇지 않으면, my_command로그에 적당한 크기의 선이 있다고 가정하여 적시에 도달하지 못할 수 있습니다.


답변

이 질문에 이미 답변 된 것으로 보이지만 더 나은 해결책이 있다고 생각합니다.

그보다는 tail | whatever당신이 정말로 원하는 것이 있다고 생각합니다 swatch. Swatch는 요청한 작업을 수행하고 로그 파일을보고 로그 라인을 기반으로 작업을 실행하도록 명시 적으로 설계된 프로그램입니다. 사용 tail|foo하려면이 작업을 수행하기 위해 터미널을 적극적으로 실행해야합니다. 반면 견본은 데몬으로 실행되며 항상 로그를 감시합니다. 견본은 모든 Linux 배포판에서 사용할 수 있습니다.

나는 당신이 그것을 시도하는 것이 좋습니다. 드라이버의 뒷면에 못을 박을 수 있다고해서 꼭 그래야하는 것은 아닙니다.

내가 찾을 수있는 견본에 대한 최고의 30 초 자습서는 여기에 있습니다 : http://www.campin.net/newlogcheck.html


답변

multitail이 기능이 기본적으로 제공되는 유틸리티 에 대해서는 아무도 언급하지 않은 것이 이상합니다 . 사용 예 중 하나 :

ping 명령의 출력을 표시하고 시간 초과가 표시되면 현재 로그인 한 모든 사용자에게 메시지를 보냅니다.

multitail -ex timeout "echo timeout | wall" -l "ping 192.168.0.1"

참조 다른 예제multitail사용을.


답변

는 스스로 일을 할 수 있습니다

그것이 얼마나 간단하고 읽기 쉬운 지 봅시다 :

mylog() {
    echo >>/path/to/myscriptLog "$@"
}

while read line;do
    case "$line" in
        *"Printer on fire"* )
            mylog Halting immediately
            shutdown -h now
            ;;
        *DHCPREQUEST* )
            [[ "$line" =~ DHCPREQUEST\ for\ ([^\ ]*)\  ]]
            mylog Incomming or refresh for ${BASH_REMATCH[1]}
            $HOME/SomethingWithNewClient ${BASH_REMATCH[1]}
            ;;
        * )
            mylog "untrapped entry: $line"
            ;;
    esac
  done < <(tail -f /path/to/logfile)

bash를 사용하지 않는 동안 regex이것은 매우 빠르게 유지 될 수 있습니다!

그러나 + 는 매우 효율적이고 흥미로운 탠덤입니다.

그러나 고부하 서버 sed의 경우 매우 빠르고 확장 성이 뛰어 나기 때문에 원하는 경우 종종 다음을 사용합니다.

while read event target lost ; do
    case $event in
        NEW )
            ip2int $target intTarget
            ((count[intTarget]++))
        ...

    esac
done < <(tail -f /path/logfile | sed -une '
  s/^.*New incom.*from ip \([0-9.]\+\) .*$/NEW \1/p;
  s/^.*Auth.*ip \([0-9.]\+\) failed./FAIL \1/p;
  ...
')

답변

그것이 내가 이것을 시작한 방법이지만 훨씬 더 정교 해졌습니다. 고려해야 할 몇 가지 사항 :

  1. 로그의 꼬리에 이미 “서버가 작동 중”이 포함되어있는 경우
  2. 테일 프로세스가 발견되면 자동으로 종료됩니다.

나는 이것의 라인을 따라 무언가를 사용한다 :

RELEASE=/tmp/${RANDOM}$$
(
  trap 'false' 1
  trap "rm -f ${RELEASE}" 0
  while ! [ -s ${RELEASE} ]; do sleep 3; done
  # You can put code here if you want to do something
  # once the grep succeeds.
) & wait_pid=$!
tail --pid=${wait_pid} -F /path/to/serverLog \
| sed "1,10d" \
| grep "server is up" > ${RELEASE}

파일에 데이터가 tail포함될 때까지 열린 채로 작동 ${RELEASE}합니다.

(가) 번 grep을 성공 :

  1. 출력에 기록 ${RELEASE}되는 것
  2. ${wait_pid}프로세스를 종료 하다
  3. 종료 tail

참고 : 시작시 생성 할 sed줄 수를 실제로 결정하고 해당 번호를 tail제거하는 것이 더 정교 할 수 있습니다 . 그러나 일반적으로 10입니다.


답변