请让我知道我们是否可以在 AWK 脚本中使用嵌套的 getline,例如:
while ( ("tail -f log" |& getline var0) > 0) {
while ( ("ls" | getline ) > 0) {
}
close("ls")
while ( ("date" | getline ) > 0) {
}
close("date")
}
close("tail -f log")
我们可以使用嵌套的 getline 功能的深度是多少?在嵌套的 getline 的任何级别都会有任何输出数据丢失吗?在实现这种风格时,我们应该确保哪些事情?
==================================================== =================================
更新===================更新==============更新============= =更新=======
要求:通过探测 QA box 和 webserver/services 日志和系统状态提供实时统计数据和错误。报告将按以下格式生成:
本地日期和时间 | 类别| 组件 | 健康)状况
假设 -: AWK 脚本将比 shell 脚本执行得更快,并具有使用其内置解析和其他功能的额外优势。
实现: - 主命令循环是 command0="tail -f -n 0 -s 5 ........."。此命令将启动一个无限循环,以提取 QA 框的服务/网络服务器的附加日志。. 请注意 -f、-s 和 -n 选项,它们可以将所有附加数据转储到日志中,在每次迭代后休眠 5 秒,然后在不从现有日志中打印任何默认内容的情况下开始。
每次迭代后,捕获并验证系统时间并在 10 秒间隔后执行各种操作系统资源命令(每次迭代之间睡眠 5 秒,处理尾部输出后 4 秒 - 假设处理所有尾部命令大约需要 1 秒,因此总共 10 秒)
我用于提取操作系统资源的各种命令是:
I. command1="vmstat | nl | tr -s '\\t '"
II. command2="sar -W 0"
III. command3="top -b -n 1 | nl | tr -s '\\t '"
IV. command4="ls -1 /tmp | grep EXIT"
在脚本中搜索相应的命令(?)并通过脚本中的while循环来计算相应命令的输出处理。注意我使用'nl'命令来简化开发/编码
最终在盒子上存在 /tmp/EXIT 文件将使脚本在从盒子中删除后退出
下面是我的脚本 - 为了自我解释,我尽可能多地添加了评论:
#Useage - awk -f script.awk
BEGIN {
command0="tail -f -n 0 -s 5 /x/web/webserver/*/logs/error_log /x/web/webserver/service/*/logs/log"
command1="vmstat | nl | tr -s '\\t '"
command2="sar -W 0"
command3="top -b -n 1 | nl | tr -s '\\t '"
command4="ls -1 /tmp | grep EXIT"
format = "%a %b %e %H:%M:%S %Z %Y"
split("", details)
split("", fields)
split("", data)
split("", values)
start_time=0
printf "\n>%s:\n\n", command0 #dummy print for debuggng command being executed
while ( (command0 |& getline var0) > 0) { #get the command output
if (start_time == 0) #if block to reset the start_time variable
{
start_time = systime() + 4
}
if (var0 ~ /==>.*<==/) { #if block to extract the file name from the tail output - outputted in '==>FileName<==' format
gsub(/[=><]/, "", var0)
len = split(var0, name, "/")
if(len == 7) {file = name[5]} else {file = name[6]}
}
if (len == 7 && var0 ~ /[Ee]rror|[Ee]xception|ORA|[Ff]atal/) { #extract the logs error statements
print strftime(format,systime()) " | Error Log | " file " | Error :" var0
}
if(systime() >= start_time) #check if curernt system time is greater than start_time as computed above
{
start_time = 0 #reset the start_time variable and now execute the system resource command
printf "\n>%s:\n\n", command1
while ( (command1 |& getline) > 0) { #process output of first command
if($1 <= 1)
continue #not needed for processing skip this one
if($1 == 2) #capture the fieds name and skip to next line
{
for (i = 1; i <= NF; i++){fields[$i] = i;}
continue
}
if ($1 == 3) #store the command data output in data array
split($0, data);
print strftime(format,systime()) " | System Resource | System | Time spent running non-kernel code :" data[fields["us"]]
print strftime(format,systime()) " | System Resource | System | Time spent running kernel code :" data[fields["sy"]]
print strftime(format,systime()) " | System Resource | System | Amount of memory swapped in from disk :" data[fields["si"]]
print strftime(format,systime()) " | System Resource | System | Amount of memory swapped to disk :" data[fields["so"]]
}
close(command1)
printf "\n>%s:\n\n", command2 #start processing second command
while ( (command2 |& getline) > 0) {
if ($4 ~ /[0-9]+[\.][0-9]+/) #check for 4th positional value if its format is of "int.intint" format
{
if( $4 > 0.0) #dummy check now to print if page swapping
print strftime(format,systime()) " | System Resource | Disk | Page rate is > 0.0 reads/second: " $4
}
}
close(command2)
printf "\n>%s:\n\n", command3 # start processing command number 3
while ( (command3 |& getline ) > 0) {
if($1 == 1 && $0 ~ /load average:/) #get the load average from the output if this is the first line
{
split($0, arr, ",")
print strftime(format,systime())" | System Resource | System |" arr[4]
}
if($1 > 7 && $1 <= 12) # print first top 5 process that are consuming most of the CPUs time
{
f=split($0, arr, " ")
if(f == 13)
print strftime(format,systime())" | System Resource | System | CPU% "arr[10]" Process No: "arr[1] - 7" Name: "arr[13]
}
}
close(command3)
printf "\n>%s:\n\n", command4 #process command number 4 to check presence of file
while ( (command4 |& getline var4) > 0) {
system("rm -rf /tmp/EXIT")
exit 0 #if file is there then remove the file and exit this script execution
}
close(command4)
}
}
close(command0)
}
输出 -:
>tail -f -n 0 -s 5 /x/web/webserver/*/logs/error_log /x/web/webserver/service/*/logs/log:
>vmstat | nl | tr -s '\t ':
Sun Dec 16 23:05:12 PST 2012 | System Resource | System | Time spent running non-kernel code :9
Sun Dec 16 23:05:12 PST 2012 | System Resource | System | Time spent running kernel code :9
Sun Dec 16 23:05:12 PST 2012 | System Resource | System | Amount of memory swapped in from disk :0
Sun Dec 16 23:05:12 PST 2012 | System Resource | System | Amount of memory swapped to disk :2
>sar -W 0:
Sun Dec 16 23:05:12 PST 2012 | System Resource | Disk | Page rate is > 0.0 reads/second: 3.89
>top -b -n 1 | nl | tr -s '\t ':
Sun Dec 16 23:05:13 PST 2012 | System Resource | System | load average: 3.63
Sun Dec 16 23:05:13 PST 2012 | System Resource | System | CPU% 12.0 Process No: 1 Name: occworker
Sun Dec 16 23:05:13 PST 2012 | System Resource | System | CPU% 10.3 Process No: 2 Name: occworker
Sun Dec 16 23:05:13 PST 2012 | System Resource | System | CPU% 6.9 Process No: 3 Name: caldaemon
Sun Dec 16 23:05:13 PST 2012 | System Resource | System | CPU% 6.9 Process No: 4 Name: occmux
Sun Dec 16 23:05:13 PST 2012 | System Resource | System | CPU% 6.9 Process No: 5 Name: top
>ls -1 /tmp | grep EXIT: