나는 다음을 수행하고 싶습니다 :
tail -f 일부 파일 { 개행 문자가 일치하거나 포함하는 경우
somestring(작업 1 수행, 작업 2 수행, ...; 추가 작업)
somestring2(다른 작업 수행)...
somestring999(다른 작업 수행도 가능)}
이것은 지금까지 내가 본 것 중 가장 가까운 것입니다.
Tail -f /mnt/zandrologs/* | awk '/GRRFIELD/ { system("echo \"test\"") }'
그러나 이는 하나의 매개변수만 인식하고 하나의 명령만 실행합니다. 여러 패턴을 인식하고 여러 명령을 실행하도록 해야 합니다. 마지막으로 bash 스크립트에 넣었습니다.
아마도 그것은 단지 가야 할 길 그 이상일지도 모르지만 그것이 내가 방금 얻은 것입니다. 지금은 문자열을 찾을 때까지 로그를 읽고 일부 쓰레기를 콘솔에 인쇄합니다(테스트). 좀 더 자세히 설명하고 싶지만 제가 하고 싶은 일의 본질에 대한 질문으로 제한하겠습니다.
몇 가지 기본적인 구문 문제에 도움을 주셔서 감사합니다.
답변1
원하는 경우 해당 방법을 계속 사용할 수 있습니다.
물론 각 일치 항목에 대해 여러 명령을 실행할 수 있으며, 다양한 명령 순서로 다양한 줄을 일치시킬 수 있습니다(더 구체적인 명령을 실행하면서 다양한 유형의 줄에 대해 일부 명령을 공유할 수도 있습니다).
전임자:
tail -f /mnt/zandrologs/* | awk '
/GRRFIELD/{ system("echo \"test\""); system("echo \"testG\""); }
/FRRFIELD/{ system("echo \"test2\""); system("echo \"testF\""); }
/FIELD/{ system("echo \"shared command for all lines containing FIELD\"");}'
원한다면 개행 문자를 생략하고 공백으로 바꿀 수도 있습니다. 또는 더 복잡한 일치를 수행할 수 있습니다. 예에서와 같이 $0(전체 행)만 일치하는 경우 행을 필드로 분할하는 오버헤드를 피하기 위해 고정 필드 및 witdh 모드에서 awk를 사용하는 것이 좋습니다.
답변2
진주파일::꼬리모듈은 이러한 작업에 이상적입니다. 배포판에 미리 패키지되어 있을 수 있습니다(예: 데비안 및 파생 제품 sudo apt-get install libfile-tail-perl
)
예를 들어
#!/usr/bin/perl
use strict;
use File::Tail;
my $dir='/mnt/zandrologs';
# Get the list of logfiles in the target directory
my @logfiles = glob("$dir/*");
# Set up an array of File::Tail objects, one for each filename.
my @logs=();
foreach (@logfiles) {
push(@logs,File::Tail->new(name => $_));
}
# Now watch those logs and do stuff when the script sees matching patterns
while (1) {
my ($nfound,$timeleft,@pending)= File::Tail::select(undef,undef,undef,undef,@logs);
if ($nfound) {
foreach my $input (@pending) {
# read the line of data from the current File::Tail object into $_
$_ = $input->read;
chomp;
# Get the filename of the current File::Tail object.
# This script doesn't use it, so it's commented out.
# my $fn = $input->{'input'};
if (m/somestring/) {
# do stuff here
# any perl code, including executing external programs with system().
} elsif (m/somestring2/) {
# do different stuff here
} elsif (m/somestring3/) {
# and more different stuff
} elsif (m/somestring999/) {
# yet more different stuff
}
}
}
};
이렇게 하면 로그 파일이 영원히(또는 종료될 때까지) 반복됩니다. 입력 파일이 회전되면 File::Tail
파일이 자동으로 닫혔다가 다시 열립니다(예: 와 유사 tail -F
).
하나 이상의 로그에 새 데이터가 있으면 이 File::Tail::select()
메서드는 다음을 반환합니다.
$nfound
- 처리할 데이터가 있는 File::Tail 개체의 수(즉, 배열의 요소 수@pending
)입니다.$timeleft
- timeout 이전에 남은 시간select()
. 그러나 이 스크립트는 시간 초과 값을 전달하지 않습니다 (배열을 제외한 모든 것을select
전달함 ).undef
@logs
@pending
- 읽지 않은 새 데이터를 포함하는 File::Tail 객체의 배열
의 각 요소는 @pending
다양한 메서드(예: read()
객체의 보류 중인 텍스트 줄 반환)와 해시 키(예: {'input'}
파일 이름 포함)를 포함하는 File::Tail 객체입니다.
자세한 내용은 및 를 참조하세요 man File::Tail
.perldoc -f select
작성된 대로 스크립트는 스크립트가 시작되기 전에 파일에 존재했던 모든 줄을 무시합니다. 마지막 내용을 읽으면 변경할 수 있습니다.N이 줄을 변경하면 전체 파일을 처음부터 변경할 수도 있습니다.
push(@logs,File::Tail->new(name => $_));
(먼저 로그 파일의 마지막 10줄을 읽으십시오):
push(@logs,File::Tail->new(name => $_, tail => 10));
또는 (처음부터 모든 로그 파일 읽기):
push(@logs,File::Tail->new(name => $_, tail => -1));
이는 이 모듈을 효율적이면서도 간단하게 사용하는 것입니다. man File::Tail
자세한 내용과 대체 용도는 참고자료를 참조하세요 . 이 모듈에는 몇 가지 훌륭한 예제 스크립트도 함께 제공됩니다.
추신: 저는 수년 동안 이 모듈을 정기적으로 사용해 왔습니다. 예를 들어, 나는 File::Tail
1990년대에 ipchains
나쁜 일을 하려는 IP 주소를 자동으로 차단하기 위해 호출되는 자체 스크립트를 유지 관리하곤 했습니다. 그러다가 fail2ban
그것이 와서 나는 그것으로 전환했습니다. 나는 오늘날까지도 로깅 스크립트를 모니터링하는 데 이를 사용하고 있습니다.