You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在awk内外使用变量:将awk变量传递给Shell的实现方案

问题

我用awk编写脚本,用于检测.cls文件中不在try/catch块内的System.debug语句,脚本能正常完成检测,但想要在检测到这类违规语句时让脚本返回失败状态(exit 1),遇到了两个问题:

  • 直接在匹配块中添加exit 1会立刻终止awk进程,无法继续检测后续的违规语句
  • 尝试用计数变量i统计违规次数,但awk内部的变量无法直接传递到外部shell环境

原awk检测脚本:

BEGIN {
  IGNORECASE = 1
}

/try\s*{/ {
  in_try_block=1
}

/catch\s*\(/ {
  in_catch_block=1
}

/}/ {
    if (in_catch_block) {
      in_catch_block=0
    } else if (in_try_block) {
      in_try_block=0
    }
  }

/System\.debug/ && !in_try_block && !in_catch_block {
  print "\033[1;31mError: System.debug found in " FILENAME ": Line " NR ": " $0 "\033[0m"
}

尝试过但变量无法传递的修改:

awk '
  BEGIN {
    IGNORECASE = 1
  }

  /try\s*{/ {
    in_try_block=1
  }

  /catch\s*\(/ {
    in_catch_block=1
  }

  /}/ {
      if (in_catch_block) {
        in_catch_block=0
      } else if (in_try_block) {
        in_try_block=0
      }
    }

  /System\.debug/ && !in_try_block && !in_catch_block {
    print "\033[1;31mError: System.debug found in " FILENAME ": Line " NR ": " $0 "\033[0m"
    i++   
  }
' "$file"

if [[ i -gt 0 ]]; then
   exit 1
fi

示例待检测类代码:

@isTest
public class GenerateDocumentTest {
    public static final String AUTH_PATH = 'Auth Path';
    public static final String SAMPLE_DATA = '{"key": "value"}';

    @TestSetup
    static void setupTestData() {
        try {
            // Insert test site
            insert new Site__c(Active__c = true, Site_Code__c = 'TestCode');

            // Insert test contact
            insert new Contact(FirstName = 'John', LastName = 'Doe', Email = 'test@example.com');

            // Insert test account
            insert new Account(Name = 'Test Account', Phone = '123456789', Email = 'account@example.com');

            // Insert test product and pricebook entry
            Product2 testProduct = new Product2(Name = 'Sample Product', IsActive = true);
            insert testProduct;

            insert new PricebookEntry(
                Product2Id = testProduct.Id,
                Pricebook2Id = Test.getStandardPricebookId(),
                UnitPrice = 100,
                IsActive = true
            );
        } catch (Exception ex) {
            System.debug('Setup error: ' + ex.getMessage());
        }
    }

    @isTest
    static void testDocumentGeneration() {
        try {
            System.debug('Testing document generation...');
            // Add test logic here
        } catch (Exception ex) {
            System.assert(false, 'Test failed: ' + ex.getMessage());
        }
    }
}

最简解决方案

方法1:通过awk END块输出计数,shell捕获后判断

让awk在处理完文件后,在END块中输出违规次数,shell通过命令替换捕获该数值,再判断是否返回失败状态。为避免错误信息干扰计数捕获,将错误信息输出到标准错误流:

# 捕获awk输出的违规次数
error_count=$(awk '
  BEGIN {
    IGNORECASE = 1
    error_count = 0
  }

  /try\s*{/ {
    in_try_block=1
  }

  /catch\s*\(/ {
    in_catch_block=1
  }

  /}/ {
      if (in_catch_block) {
        in_catch_block=0
      } else if (in_try_block) {
        in_try_block=0
      }
    }

  /System\.debug/ && !in_try_block && !in_catch_block {
    # 错误信息输出到stderr,不干扰计数捕获
    print "\033[1;31mError: System.debug found in " FILENAME ": Line " NR ": " $0 "\033[0m" > "/dev/stderr"
    error_count++
  }

  # 最后输出计数到stdout,供shell捕获
  END {
    print error_count
  }
' "$file")

# 根据计数判断是否返回失败状态
if [[ "$error_count" -gt 0 ]]; then
  exit 1
fi

方法2:直接通过awk的退出状态判断

如果只需要知道是否存在违规(不需要具体次数),可以让awk在END块中根据计数设置退出状态,shell直接判断awk的返回值:

awk '
  BEGIN {
    IGNORECASE = 1
    error_count = 0
  }

  /try\s*{/ {
    in_try_block=1
  }

  /catch\s*\(/ {
    in_catch_block=1
  }

  /}/ {
      if (in_catch_block) {
        in_catch_block=0
      } else if (in_try_block) {
        in_try_block=0
      }
    }

  /System\.debug/ && !in_try_block && !in_catch_block {
    print "\033[1;31mError: System.debug found in " FILENAME ": Line " NR ": " $0 "\033[0m"
    error_count++
  }

  # 有违规则返回非0状态
  END {
    exit (error_count > 0 ? 1 : 0)
  }
' "$file"

# 判断awk的退出状态,非0则触发失败
if [[ $? -ne 0 ]]; then
  exit 1
fi

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 21:35:17