다음 구조의 구성 파일(Nagios)이 있습니다.
define service{
use pruebaspre-service,srv-pnp
host_name server1.es
servicegroups pruebasdatasourcesoaspre-servicegroup,pruebaspre-servicegroup
service_description Estado DataSource - cfio JUVEPoolDSPoolDS
check_command check_ds_oas!cfio!JUVEPoolDSPoolDS!/opt/oracle/ias10g/10.1.2!1!0
}
define service{
use pruebaspre-service,srv-pnp
host_name server1.es
servicegroups pruebasdatasourcesoaspre-servicegroup,pruebaspre-servicegroup
service_description Estado DataSource - cfio REMEPoolDS
check_command check_ds_oas!cfio!REMEPoolDS!/opt/oracle/ias10g/10.1.2!1!0
}
define service{
use pruebaspre-service,srv-pnp
host_name server2.es
servicegroups pruebasdatasourcesoaspre-servicegroup,pruebaspre-servicegroup
service_description Estado DataSource - cfio iris_usr_irisPoolDS
check_command check_ds_oas!cfio!iris_usr_irisPoolDS!/opt/oracle/ias10g/10.1.3!1!0
}
define service{
use pruebaspre-service,srv-pnp
host_name server2.es
servicegroups pruebasdatasourcesoaspre-servicegroup,pruebaspre-servicegroup
service_description Estado DataSource - cfio REMEPoolDS
check_command check_ds_oas!cfio!REMEPoolDS!/opt/oracle/ias10g/10.1.2!1!0
}
define service{
use pruebaspre-service,srv-pnp
host_name server2.es
servicegroups pruebasdatasourcesoaspre-servicegroup,pruebaspre-servicegroup
service_description Estado DataSource - cfio redt2_usr_redt2PoolDS
check_command check_ds_oas!cfio!redt2_usr_redt2PoolDS!/opt/oracle/ias10g/10.1.3!1!0
}
check_command
이 파일에 새 서비스를 등록하려면 먼저 서비스가 존재하는지 확인해야 하며, 이를 위해서는 서비스가 host_name
등록되지 않았는지 확인해야 합니다 .
예를 들어, 다음을 등록하고 싶습니다.
define service {
use pre-service tests, srv-pnp
host_name server1.es
servicegroups testsdatasourcesoaspre-servicegroup, pre-servicegroup tests
service_description DataSource Status - cfio REMEPoolDS
check_command check_ds_oas! cfio! REMEPoolDS! /opt/oracle/ias10g/10.1.2! 1! 0
}
그래서 내가 찾아야 할 파일에는 존재하지 않습니다.
while 루프를 사용하여 파일을 읽으려고 시도했는데 발견되었을 때
check_command check_ds_oas! Cfio! REMEPoolDS! /Opt/oracle/ias10g/10.1.2! 1! 0
다음은 아닌 것 같아
host_name server1.es
V_NAGIOS_COMMAND=check_ds_oas!cfio!REMEPoolDS!/opt/oracle/ias10g/10.1.2!1!0
if [ `grep ${V_NAGIOS_COMMAND} --count $V_FILE_NAGIOS` -ge 1 ] ; then
while read LINEA_CONFIG
do
V_DIRECTIVA=`echo $LINEA_CONFIG| awk '{print $1} '`
V_VALOR_DIRECTIVA=`echo $LINEA_CONFIG| awk '{print $2} '`
if [ $V_DIRECTIVA = check_command ]&&[ $V_VALOR_DIRECTIVA = $V_NAGIOS_COMMAND ]; then
V_COMANDO_ENCONTRADO=1
elif [ $V_DIRECTIVA = host_name ]&& [ $V_COMANDO_ENCONTRADO = 1 ] ; then
if [ $V_VALOR_DIRECTIVA = $V_MAQUINA ] ; then
((V_EXISTEN_DATOS++))
return 1
else
V_COMANDO_ENCONTRADO=0
fi
fi
done < <(tac $V_FILE_NAGIOS| grep -vE "^#|^$")
fi
하지만 느립니다.
답변1
귀하의 요구 사항을 잘 이해한다면 sed
입력 스트림 내에서 "하위 스트림"을 분리할 수 있으므로 이 작업을 잘 수행할 수 있는 것처럼 보입니다.
POSIX여야 합니다.
sed -n "/^define service/,/^}/{/^[[:blank:]]\\{1,\}host_name[[:blank:]]\\{1,\\}${V_MAQUINA}/,/^}/{\\%^[[:blank:]]\\{1,\\}check_command[[:blank:]]\\{1,\\}${V_NAGIOS_COMMAND}%{p;q}}}" file
또는 GNU sed를 사용할 수 있는 경우 문자열의 이스케이프를 줄일 수 있습니다.
sed -En "/^define service/,/^\\}/{/^[[:blank:]]+host_name[[:blank:]]+${V_MAQUINA}/,/^\\}/{\\%^[[:blank:]]+check_command[[:blank:]]+${V_NAGIOS_COMMAND}%{p;q}}}" file
설명하다:
sed -En # use Extended Regular Expressions, and don't print by default
# main `sed` script for entire stream
/^define service/,/^\\}/ # between 'define service' and '}'
{ # sub-stream: between specified 'host_name' and '}'
/^[[:blank:]]+host_name[[:blank:]]+${V_MAQUINA}/,/^\\}/
{ # look for specified 'check_command', using '%' because '/' can be in command
\\%^[[:blank:]]+check_command[[:blank:]]+${V_NAGIOS_COMMAND}%
{p;q} # if found, print line and quit `sed`
}
}
check_command
정규식으로 구분된 "스니펫"에서 행이 발견되면 해당 행을 인쇄하고 file
, 그렇지 않으면 아무것도 인쇄하지 않습니다.
따라서 반환된 문자열이 존재하는지 확인하면 됩니다.
sed
아무것도 인쇄되지 않을 때도 0으로 종료되므로 종료 상태를 확인하지 않습니다 .
몇 가지 추가 참고 사항:
- 쉘에서 큰따옴표 안에 있기 때문에
\\
1을 표현 해야 합니다 .\
$V_MAQUINA
쉘 변수를 사용하려면 큰따옴표를 사용합니다.$V_NAGIOS_COMMAND
%
이전 정규식에서 정규식 구분 기호로 선택했지만 변수 에 표시되지 않는 문자를 자유롭게 선택할 수 있습니다.$V_NAGIOS_COMMAND
답변2
전혀:
/^define service/{
found_command=0
found_host=0
while (getline && $0 !~ "^}") {
# test host
if($1 == "host_name") {
if ($2 == new_host) {
found_host=1
}else{
next
}
}
# test check_command
if($1 == "check_command"){
cmd = gensub(/^\s*check_command\s*/, "", 1)
if (cmd == new_command) {
found_command=1
}else{
next
}
}
}
if (found_command && found_host)
exit 1
}
다음과 같이 사용할 수 있습니다.
new_host='...'
new_command='...'
if awk -v new_host="$new_host" -v new_command="$new_command" -f script.awk cfg_file ; then
echo "you can register it now"
fi