AWK条件判断输出异常:预期返回Failed实际得到Ok
问题分析与解决
问题背景
我写了一段Shell脚本检测crontab中的定时任务,明明crontab里存在目标任务条目,预期输出应该是「FAILED - sop job should not be scheduled」,但实际却返回了「OK - sop job not scheduled」。我认为NR==0应该为假,想搞懂$0<1在这里的作用是什么?
相关代码与输出
crontab条目
# comment x 00 5 * * * /opt/vol/scripts/volumes.sh -m SOP
检测脚本
crontab -l | grep -v "^#" | grep "/opt/vol/scripts/volumes.sh" | grep "SOP" | awk 'END { if (NR==0 || $0<1) print "OK - sop job not scheduled"; else print "FAILED - sop job should not be scheduled"; }'
错误输出
OK - sop job not scheduled
预期输出
FAILED - sop job should not be scheduled
问题原因
$0<1的实际作用(错误逻辑)
在awk的END块中,$0代表的是最后一行输入的内容,而非行数或计数。你的目标行是00 5 * * * /opt/vol/scripts/volumes.sh -m SOP,awk会尝试把这个字符串转成数字(只取开头的数字部分),结果是0,所以0<1的判断为true。逻辑判断出错
当grep找到目标行后,awk接收到这一行输入,NR(已处理的总行数)会是1,所以NR==0为false,但$0<1为true,逻辑或||的结果还是true,因此脚本执行了print "OK..."的分支,和预期相反。
解决方法
修正原脚本
直接去掉错误的$0<1判断,只保留NR==0的逻辑即可:
crontab -l | grep -v "^#" | grep "/opt/vol/scripts/volumes.sh" | grep "SOP" | awk 'END { if (NR==0) print "OK - sop job not scheduled"; else print "FAILED - sop job should not be scheduled"; }'
更简洁的写法(用awk替代所有grep)
减少管道操作,直接用awk完成过滤和判断,效率更高:
crontab -l | awk '!/^#/ && /\/opt\/vol\/scripts\/volumes.sh/ && /SOP/ { found=1 } END { if (found) print "FAILED - sop job should not be scheduled"; else print "OK - sop job not scheduled" }'
内容的提问来源于stack exchange,提问作者AashkaTe
相关产品推荐
相关产品推荐

