tboy1337/Blinter
GitHub: tboy1337/Blinter
Blinter 是一款针对 Windows 批处理文件的静态分析与代码检查工具,旨在帮助开发者识别语法错误、安全漏洞、性能问题和风格缺陷。
Stars: 47 | Forks: 0
# Blinter
**Blinter** 是一个针对 Windows 批处理文件(`.bat` 和 `.cmd`)的 linter。它提供全面的静态分析,以识别语法错误、安全漏洞、性能问题和风格问题。Blinter 可帮助您编写更安全、更可靠且更易于维护的批处理脚本。即使在 2026 年,批处理文件也值得拥有专业的工具!
- ✅ **可配置选项** - 可配置的规则,`--verbose`/`--quiet` 日志记录,强大的错误处理
- ✅ **Unicode 支持** - 支持国际字符和文件名
- ✅ **性能优化** - 高效处理大型批处理文件
## 功能 ✨
### 🔍 **规则类别**
- **内置规则** -- 注册表目前提供涵盖 5 个严重级别的 **147** 条规则(参见 `blinter.rules.registry.RULE_COUNT`;编号间隙反映了已废弃或合并的规则 ID)
- **错误级别 (E001-E999)**:阻止执行的关键语法错误
- **警告级别 (W001-W999)**:潜在的运行时问题和不良做法
- **风格级别 (S001-S999)**:代码格式和可读性改进
- **安全级别 (SEC001+)**:安全漏洞和危险操作
- **性能级别 (P001-P999)**:优化机会和效率提升
📖 **有关包含示例和实现细节的完整规则说明,请参见 [Batch-File-Linter-Requirements.md](https://github.com/tboy1337/Blinter/blob/main/docs/Batch-File-Linter-Requirements.md)**
### 📋 **输出格式**
- **规则代码**:每个问题都有一个唯一的标识符(例如 E002、W005、SEC003)
- **清晰的解释**:详细描述每个问题为何重要
- **可操作的建议**:关于如何修复问题的具体指导
- **逐行分析**:每个问题的精确位置
- **上下文信息**:有关检测到的问题的额外详细信息
### 🚀 **高级分析**
- **静态代码分析**:检测无法到达的代码和逻辑错误
- **高级变量扩展**:验证百分号加波浪号语法(%~n1)、字符串操作和 SET /A 算术
- **特定命令验证**:FOR 循环变体、IF 语句最佳实践、已弃用的命令检测
- **变量追踪**:识别未定义的变量和不安全的使用模式
- **安全扫描**:路径遍历攻击、命令注入风险、不安全的临时文件创建
- **性能优化**:DIR 标志优化、不必要的输出检测、字符串操作效率
- **跨平台兼容性**:针对 Windows 版本问题和已弃用命令发出警告
- **大文件处理**:通过性能监控高效处理大型批处理文件
- **强大的编码检测**:处理 UTF-8、UTF-16、Latin-1 及另外 6 种编码格式
- **高级转义技术**:验证脱字符转义序列、多级转义和续行符
- **专业的 FOR 命令分析**:检查 usebackq、正确的 token 处理、分隔符和 skip 选项
- **进程管理最佳实践**:Timeout 命令使用、进程验证和重启模式
- **增强的安全模式**:用户输入验证、临时文件安全和自修改检测
## 安装 🛠️
### 🚀 快速开始(推荐)
**选项 1:通过 pip 安装(推荐)**
```
pip install Blinter
```
**选项 2:独立可执行文件(无需 Python)**
如果您倾向于使用独立的 `.exe` 而不是 pip,请使用一行安装程序:
```
curl -L https://raw.githubusercontent.com/tboy1337/Blinter/main/scripts/install_blinter.cmd -o install_blinter.cmd && (call install_blinter.cmd || cd .) && del install_blinter.cmd
```
这会将最新的 `blinter.exe` 安装到 `%LOCALAPPDATA%\Programs\Blinter\bin`,将其添加到您的用户 `PATH` 中,并自动处理更新。安装后请重启终端或 IDE,以使 `PATH` 的更改生效。
**手动下载 zip 包(备选方案):**
- 从 [GitHub Releases](https://github.com/tboy1337/Blinter/releases) 下载最新的 `Blinter-v1.0.x.zip`
- 首选上述的一行安装程序;它能让 `blinter` 保留在您的 `PATH` 中,无需手动设置。
- ⚠️ **注意**:由于 PyInstaller 的运行时解包行为,某些防病毒软件可能会将该可执行文件误报。该可执行文件是完全安全的(所有源代码均开放供检查)。**我们建议使用 pip 安装来避免此问题。**
### 卸载
**独立可执行文件(一行安装程序):**
```
curl -L https://raw.githubusercontent.com/tboy1337/Blinter/main/scripts/uninstall_blinter.cmd -o uninstall_blinter.cmd && call uninstall_blinter.cmd && del uninstall_blinter.cmd
```
**pip 安装:**
```
pip uninstall Blinter
```
### 🔧 手动安装
1. 克隆仓库:
```
git clone https://github.com/tboy1337/Blinter.git
cd Blinter
```
2.(可选)创建虚拟环境:
```
python -m venv venv
venv\Scripts\activate.bat
```
3. 安装开发依赖(包含运行时依赖):
```
pip install -e ".[dev]"
```
### 前置条件
- **Python 3.12+**(pip 安装和开发必需)
- **Windows 操作系统**(独立可执行文件必需)
## 使用方法 📟
### 基本用法
**如果通过 pip 安装:**
```
# 分析单个 batch 文件
blinter script.bat
# 或者
python -m blinter script.bat
# 递归分析目录中的所有 batch 文件
python -m blinter /path/to/batch/files
# 仅分析目录中的 batch 文件(非递归)
python -m blinter /path/to/batch/files --no-recursive
# 分析并附带摘要
python -m blinter script.bat --summary
# 分析脚本及其调用的具有共享变量上下文的脚本
python -m blinter script.bat --follow-calls
# 使用自定义最大行长进行分析
python -m blinter script.bat --max-line-length 120
# 创建配置文件
python -m blinter --create-config
# 忽略配置文件
python -m blinter script.bat --no-config
# 获取帮助
python -m blinter --help
# 获取版本
python -m blinter --version
```
**如果使用独立可执行文件(通过安装程序或手动下载):**
```
# 在使用一行安装程序后,在 PATH 上使用 blinter。
# 手动 zip 下载使用带版本号的名称:Blinter-v1.0.x.exe
# 分析单个 batch 文件
blinter script.bat
# 递归分析目录中的所有 batch 文件
blinter /path/to/batch/files
# 仅分析目录中的 batch 文件(非递归)
blinter /path/to/batch/files --no-recursive
# 分析并附带摘要
blinter script.bat --summary
# 分析脚本及其调用的具有共享变量上下文的脚本
blinter script.bat --follow-calls
# 使用自定义最大行长进行分析
blinter script.bat --max-line-length 120
# 获取帮助
blinter --help
# 获取版本
blinter --version
```
**如果使用本地开发安装:**
```
pip install -e .
# 分析单个 batch 文件
blinter script.bat
# 递归分析目录中的所有 batch 文件
blinter /path/to/batch/files
# 仅分析目录中的 batch 文件(非递归)
blinter /path/to/batch/files --no-recursive
# 分析并附带摘要
blinter script.bat --summary
# 分析脚本及其调用的具有共享变量上下文的脚本
blinter script.bat --follow-calls
# 使用自定义最大行长进行分析
blinter script.bat --max-line-length 120
# 创建配置文件
blinter --create-config
# 忽略配置文件
blinter script.bat --no-config
# 获取帮助
blinter --help
# 获取版本
blinter --version
```
### 命令行选项
- ``:批处理文件(`.bat` 或 `.cmd`)的路径,或者包含批处理文件的目录
- `--summary`:显示发现问题的汇总统计信息
- `--severity`:已弃用的旧标志(会发出警告,无实际效果);请改用 `blinter.ini` 中的 `min_severity`
- `--max-line-length `:设置 S011 规则的最大行长(默认:100)
- `--no-recursive`:处理目录时,仅分析指定目录中的文件(不包含子目录)
- `--follow-calls`:自动分析由 CALL 语句调用的脚本并合并它们的变量上下文。启用后,在被调用脚本(包括在深度和文件限制范围内间接调用的脚本)中定义的变量将被识别为调用脚本中的“已定义”变量(具有位置感知:仅在 CALL 语句之后)。这消除了配置脚本中未定义变量的误报
- `--config `:从自定义配置文件加载设置,而不是使用当前目录下的 `blinter.ini`
- `--no-config`:即使存在也不使用配置文件(blinter.ini)
- `--create-config`:创建默认的 blinter.ini 配置文件并退出
- `--create-config --force`:创建默认配置时覆盖现有的 blinter.ini
- `--verbose`:显示详细的日志输出(INFO 级别)
- `--quiet`:抑制非错误日志输出(仅 ERROR 级别)
- `--help`:显示帮助菜单和规则类别
- `--version`:显示版本信息
**注意:** 命令行选项会覆盖配置文件中的设置。Blinter 会自动在当前目录中查找 `blinter.ini`。
### 配置文件选项 📝
| 部分 | 设置 | 描述 | 默认值 |
|---------|---------|-------------|---------|
| `[general]` | `recursive` | 分析文件夹时搜索子目录 | `true` |
| `[general]` | `show_summary` | 分析后显示汇总统计信息 | `false` |
| `[general]` | `max_line_length` | S011 规则的最大行长 | `100` |
| `[general]` | `max_scan_files` | 目录中最多扫描的批处理文件数 | `1000` |
| `[general]` | `follow_calls` | 在共享变量上下文下分析由 CALL 语句调用的脚本 | `false` |
| `[general]` | `min_severity` | 报告的最低严重级别 | None(全部) |
| `[rules]` | `enabled_rules` | 以逗号分隔的独占启用规则列表 | None(全部启用) |
| `[rules]` | `disabled_rules` | 以逗号分隔的禁用规则列表 | None |
**配置说明:**
- 当同时设置 `enabled_rules` 和 `disabled_rules` 时,规则必须出现在 `enabled_rules` 中才能运行;随后 `disabled_rules` 将从该允许列表中移除匹配项。
- `blinter.ini` 中的 `max_line_length` 控制风格规则 S011/S020(默认 `100`)。单行的硬性读取限制为 `10,000` 个字符(引擎中的 `MAX_LINE_LENGTH`);超过此长度的行将在 linting 前被拒绝。
**规则迁移:** 风格规则 `S006` 已合并至 `S022`。如果您的 `blinter.ini` 在 `enabled_rules` 或 `disabled_rules` 中引用了 `S006`,请改用 `S022`。
### 命令行覆盖
命令行选项始终覆盖配置文件设置:
```
# 使用 config 文件设置
python -m blinter myscript.bat
# 覆盖 config 以显示摘要
python -m blinter myscript.bat --summary
# 分析脚本及其调用的具有共享变量上下文的脚本
python -m blinter myscript.bat --follow-calls
# 使用自定义行长覆盖 config
python -m blinter myscript.bat --max-line-length 100
# 完全忽略 config 文件
python -m blinter myscript.bat --no-config
```
### 🔕 内联抑制注释
您可以使用特殊注释直接在批处理文件中抑制特定的 linter 警告:
#### 抑制下一行
```
REM LINT:IGNORE E009
ECHO '' .... Represents a " character
```
#### 抑制当前行
```
REM LINT:IGNORE-LINE S013
```
#### 抑制多个规则
```
REM LINT:IGNORE E009, W011, S004
ECHO Unmatched quotes "
```
#### 抑制行上的所有规则
```
REM LINT:IGNORE
REM This line and the next will be ignored for all rules
```
**支持的格式:**
- `REM LINT:IGNORE
` - 在**下一行**抑制特定规则
- `REM LINT:IGNORE` - 在**下一行**抑制所有规则
- `REM LINT:IGNORE-LINE ` - 在**同一行**抑制特定规则
- `REM LINT:IGNORE-LINE` - 在**同一行**抑制所有规则
- `:: LINT:IGNORE ` - 备选注释语法(也受支持)
**使用场景:**
- 抑制无法修复的误报
- 忽略对最佳实践的有意偏离
- 处理文档或帮助文本中的边缘情况
- 在开发期间暂时忽略问题
### 🐍 **Programmatic API 使用**
Blinter 从顶层 `blinter` 包公开了一个小型的公共 API:
```
from blinter import (
BlinterConfig,
RuleSeverity,
lint_batch_file,
load_config,
)
# 基本用法
issues = lint_batch_file("script.bat")
for issue in issues:
print(f"Line {issue.line_number}: {issue.rule.name} ({issue.rule.code})")
# 使用自定义配置
config = BlinterConfig(
max_line_length=80,
disabled_rules={"S007", "S011"},
min_severity=RuleSeverity.WARNING,
)
issues = lint_batch_file("script.bat", config=config)
# 处理结果
for issue in issues:
print(f"Line {issue.line_number}: {issue.rule.name}")
print(f" {issue.rule.explanation}")
print(f" Fix: {issue.rule.recommendation}")
# Thread-safe 设计允许安全的并发使用
from concurrent.futures import ThreadPoolExecutor
files = ["script1.bat", "script2.cmd", "script3.bat"]
with ThreadPoolExecutor(max_workers=4) as executor:
results = list(executor.map(lint_batch_file, files))
```
高级集成商可以直接从子模块导入:
```
from blinter.rules.registry import RULES
from blinter.patterns import DANGEROUS_COMMAND_PATTERNS
from blinter.checkers.syntax import _check_syntax_errors
```
有关完整的模块映射和扩展点,请参见 [docs/Architecture.md](docs/Architecture.md)。
### 包布局
```
src/blinter/
__init__.py # Public API
models.py # BlinterConfig, LintIssue, Rule
rules/ # RULES registry
patterns.py # Dangerous-command patterns
parsing/ # Structure and context analysis
checkers/ # Rule implementations by category
engine/ # lint_batch_file orchestration
io/ # Encoding and file discovery
config/ # blinter.ini loading
output/ # CLI formatters
cli/ # Command-line entry point
```
```
flowchart BT
models --> constants
constants --> patterns
patterns --> rules
rules --> parsing
parsing --> checkers
checkers --> engine
engine --> cli
config --> cli
io --> engine
```
### 🔧 **配置选项(`BlinterConfig`)**
| 参数 | 类型 | 默认值 | 描述 |
|-----------|------|---------|-------------|
| `recursive` | `bool` | `True` | 对文件夹进行 lint 时搜索子目录 |
| `show_summary` | `bool` | `False` | 在 CLI 输出中显示汇总统计信息 |
| `max_line_length` | `int` | `100` | S011 规则的最大行长 |
| `follow_calls` | `bool` | `False` | Lint 由 `CALL` 语句引用的脚本 |
| `scan_root` | `str` \| `None` | `None` | 用于 `--follow-calls` 限制的根路径(CLI 会自动设置) |
| `enabled_rules` | `Set[str]` | 为空 | 如果非空,则仅运行这些规则代码 |
| `disabled_rules` | `Set[str]` | 为空 | 要跳过的规则代码 |
| `min_severity` | `RuleSeverity` \| `None` | `None` | 报告的最低严重级别(通过 `blinter.ini` 设置;没有专用的 CLI 标志) |
*注意:E006 使用了 `E` 前缀,但报告为**警告**级别(这是有意为之——环境变量可以在外部设置)。*
### 支持的文件类型
- `.bat` 文件(传统批处理文件)
- `.cmd` 文件(现代 Windows 推荐)
- 支持 **Unicode 文件名**和国际字符
- 通过性能监控高效处理**大文件**
### 📁 **目录处理**
Blinter 可以通过强大的选项分析整个目录下的批处理文件:
- **递归分析**:自动查找并处理目录及子目录中的所有 `.bat` 和 `.cmd` 文件
- **非递归模式**:使用 `--no-recursive` 仅分析指定目录中的文件
- **批处理**:通过合并报告高效处理多个文件
- **容错性**:即使某些文件存在编码或权限问题,也会继续处理其他文件
- **进度跟踪**:显示每个文件的详细结果以及合并的汇总统计信息
**示例:**
```
# Pip 安装:
blinter ./my-batch-scripts # Analyze all files recursively
blinter . --no-recursive # Current directory only
blinter ./scripts --summary # With summary statistics
# 独立可执行文件(安装程序或手动 zip):
blinter ./my-batch-scripts # Analyze all files recursively
blinter . --no-recursive # Current directory only
blinter ./scripts --summary # With summary statistics
# 仅限手动 zip(带版本号的 exe 名称):
Blinter-v1.0.x.exe ./my-batch-scripts
# 本地开发安装:
blinter ./my-batch-scripts # Analyze all files recursively
blinter . --no-recursive # Current directory only
blinter ./scripts --summary # With summary statistics
```
## 🔥 **集成示例**
### CI/CD 集成
```
# 示例 GitHub Actions workflow
- name: Lint Batch Files
run: |
python -c "
from blinter import lint_batch_file
from blinter import RuleSeverity
import sys
issues = lint_batch_file('deploy.bat')
fatal = [i for i in issues if i.rule.severity in (RuleSeverity.ERROR, RuleSeverity.SECURITY)]
if fatal:
print(f'Found {len(fatal)} critical issues (errors or security)!')
sys.exit(1)
print(f'Batch file passed with {len(issues)} total issues')
"
```
`blinter` CLI 退出代码:
| 代码 | 含义 |
|------|---------|
| **0** | 成功:没有错误或安全发现,并且每个发现的主文件都已被处理 |
| **1** | Lint 失败:存在任何**错误**或**安全**发现、CLI/路径错误、没有可处理的文件、跳过了任何主目标文件,或者发现的所有文件均无法读取 |
| **2** | 意外的内部错误 |
如果退出代码原本为 0,那么仅凭警告和风格问题不会导致运行失败。
## 开发
在发布之前,安装开发依赖并在本地运行质量门控:
```
pip install -e ".[dev]"
# 或者:pip install -e . && pip install -r requirements-dev.txt
py scripts/verify.py # full gate (format, mypy, pylint, bandit, pip-audit, pytest)
py scripts/verify.py --fix # auto-fix whitespace and imports first
```
的手动步骤(与 `verify.py` 检查相同):
```
py -m pytest
py -m mypy src/blinter tests
py -m pylint src/blinter --output-format=text > pylint-output.txt
py -m bandit -r src/blinter
py -m pip-audit -r requirements.txt -r requirements-dev.txt
py -m black --check src tests
py -m isort --check-only src tests
```
可选的语料库回归测试(需要本地的 `batch-script-examples/` 目录):
```
py scripts/corpus_lint.py
```
测试套件强制要求达到 90% 的分支覆盖率(`pytest.ini`、`.coveragerc`)。CI 会构建并发布包,但不会运行测试;请将本地通过 `pytest` 运行视为发布门控。
有关模块布局和扩展点,请参见 [docs/Architecture.md](docs/Architecture.md)。
## 贡献 🤝
**欢迎贡献!**
### 贡献方式
- 🐛 报告 bug 或问题
- 💡 建议新规则或功能
- 📖 改进文档
- 🧪 添加测试用例
- 🔧 提交 bug 修复或增强功能
**特别感谢 [BrainWaveCC](https://github.com/BrainWaveCC) 在 bug 搜寻方面提供的所有帮助。**
## 许可证 📄
本项目基于 GNU Affero General Public License v3.0 或更高版本 (AGPL-3.0-or-later) 获得许可 - 详情请参见 [COPYING](https://github.com/tboy1337/Blinter/blob/main/COPYING)。
[字母 b 图标由 Acidmit 创建 - Flaticon](https://www.flaticon.com/free-icons/letter-b)标签:Apache Flink, SOC Prime, Windows批处理, 云安全监控, 代码审查工具, 代码规范检查, 安全专业人员, 开发工具, 漏洞挖掘, 逆向工具, 静态分析