You need to enable JavaScript to run this app. bash脚本内grep返回换行符、命令行直接执行却返回空的问题排查
优惠活动
大模型
产品
解决方案
定价
更多

bash脚本内grep返回换行符、命令行直接执行却返回空的问题排查

基于正则的SQL Lint脚本执行异常说明

实际异常现象

  • 目标:通过正则表达式完成SQL代码的lint校验,目前已写出可初步运行的实现逻辑,但执行表现和预期不一致
  • 异常表现:将grep相关逻辑写入bash脚本执行时,grep输出会附带换行符;但在命令行直接执行完全相同的grep命令时,却返回空结果,怀疑脚本本身存在逻辑问题

当前使用的脚本实现

LINT='pcregrep -Mi'
PATTERN="(^\s*SELECT(.*)(\n|\r\n|\r))((^(\s*--(.*))|^(\s*(.*),))(\n|\r\n|\r))*(^(\s*--(.*))(\n|\r\n|\r))*(^\s*FROM(.*))"
files=$(git diff --name-only --diff-filter=ACM | grep "\.sql$")
if [ "$files" = "" ]; then
    exit 0
fi

pass=true

echo -e "\nLinting SQL:\n"

for file in ${files}; do
    result=$($LINT $PATTERN ${file} | grep "No syntax errors detected in ${file}")
    if [ "$result" != "" ]; then
        echo -e "\t\033[32mPassed: ${file}\033[0m"
    else
        echo -e "\t\033[31mFailed: ${file}\033[0m"
        echo $result | tr ' \n' '#$'
        echo "$($LINT $PATTERN ${file})"
        pass=false
    fi
done

测试用的SQL样例

SELECT
    val1,
    val2,
    val3 
FROM

脚本存在的核心问题

  • 校验判断逻辑完全错位:当前代码用pcregrep的输出匹配固定字符串No syntax errors detected in ${file}作为校验通过的判断依据,但pcregrep本身的输出逻辑是「匹配到符合规则的内容时直接打印匹配行」,不会主动生成“无语法错误”类的提示文本,等于这段grep逻辑永远匹配不到目标内容,校验分支完全走偏。
  • 命令行与脚本执行结果不一致的根因:脚本中通过变量传递执行参数时,字符串会经过一次bash变量展开,最终传给pcregrep的正则字符串、文件路径参数,和在命令行直接手动敲写的命令参数存在细微差异(比如特殊字符转义、多空格拆分),才会出现命令行返回空、脚本输出带换行的表现差异。
  • 空值判断逻辑不严谨:当前用if [ "$files" = "" ]判断是否存在需要校验的SQL文件,实际files变量在多文件场景下是带换行的多行字符串,直接做全字符串等值比较的逻辑鲁棒性差,容易出现判断错误。
  • 违规匹配的逻辑未对齐:当前写的PCRE正则的设计目标是匹配「SELECT后所有列项均以逗号结尾、直接衔接FROM子句」的违规场景,即匹配到内容就说明存在SQL语法问题,但脚本中并未直接利用pcregrep的退出码做判断,反而绕了不必要的grep步骤。
  • 冗余残留代码:脚本中echo $result | tr ' \n' '#$'这段逻辑,因为$result永远为空,实际执行没有任何有效输出,属于从其他校验脚本复制过来的无意义残留。

参考修正方向

  • 直接利用pcregrep的退出码做结果判断:匹配到违规内容时pcregrep返回退出码0,未匹配到任何内容时返回退出码1,无需额外通过grep匹配固定文本判断结果
  • 定义执行命令时优先使用数组格式,避免变量展开带来的参数错位问题
  • 空值判断统一使用[ -z "$变量名" ]的语法,适配多值场景下的判断需求

内容的提问来源于stack exchange,提问作者Reed Richards

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 18:27:03