Shell脚本条件分支异常:匹配任意关键字仅执行最后分支
看起来你的脚本里有几个关键问题导致了不管匹配什么关键字都走最后一个分支,我帮你梳理一下并给出修复方案:
问题分析
大小写不匹配导致前置条件失效
你第一个if里的grep用了小写的"select"且没加忽略大小写的参数,但Hive日志里的SQL语句通常是大写格式(比如SELECT),这直接导致第一个条件永远为假,程序会直接跳到后面的分支。另外用grep -c统计行数的方式有点冗余,用grep的退出状态判断更高效准确。错误读取整个日志而非当前行
在if分支里,你直接读取整个hive-server2.log的最后一个SELECT行,这会导致逻辑混乱——哪怕当前处理的是CREATE语句,只要日志历史里有SELECT记录,QueryResult都会被错误赋值,完全偏离了实时处理当前日志行的需求。
修复后的脚本
# 用进程替换代替管道,避免子shell导致变量丢失 while read LINE do # 检查当前行是否包含SELECT(忽略大小写) if echo "$LINE" | grep -qi "select"; then AuditTypeID=15 # 从当前行提取完整SELECT语句 QueryResult=$(echo "$LINE" | grep -oEi 'SELECT .*') # 检查当前行是否包含CREATE(忽略大小写) elif echo "$LINE" | grep -qi "create"; then AuditTypeID=13 # 从当前行提取CREATE EXTERNAL TABLE语句(补全你未写完的正则示例) QueryResult=$(echo "$LINE" | grep -oEi 'CREATE EXTERNAL TABLE [a-zA-Z0-9_]+') # 可选:处理未匹配到关键字的情况 else echo "Unmatched log line: $LINE" fi # 这里可以添加后续的审计逻辑,比如写入数据库或文件 echo "Audit record: TypeID=$AuditTypeID, Query=$QueryResult" done < <(tail -n 0 -F hive-server2.log)
关键修改说明
grep -qi替代grep -c:-q让grep静默运行,只返回退出状态(匹配成功返回0,失败返回1),-i忽略大小写,确保无论日志里是大写还是小写的关键字都能匹配到,判断逻辑更高效。- 从当前行提取内容:不再读取整个日志文件,而是直接对当前处理的
LINE进行提取,保证获取的是触发当前分支的日志内容。 - 进程替换替代管道:
< <(tail ...)的写法让while循环在当前shell中执行,避免了管道导致的子shell变量丢失问题(如果你的脚本需要在循环外使用AuditTypeID等变量,这个修改很关键)。
内容的提问来源于stack exchange,提问作者Teju Priya
相关产品推荐
相关产品推荐

