关于 batch-files
batch-files 是用于创建、编辑、调试和维护 Windows .bat 与 .cmd 脚本的技能,涵盖 cmd.exe 语法及自动化、命令行工具和系统管理实践。
主要功能
- 01批处理语法与变量处理
- 02控制流和参数解析
- 03错误处理与退出代码
- 04文件、文本、网络和系统命令
- 05脚本结构与实践建议
适用场景
- 01自动执行文件操作或备份
- 02构建基于 PATH 的命令行脚本
- 03排查引号或变量展开问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ github/ awesome-copilot --skill batch-files安装后在 Claude Code 中输入/batch-files确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/executable.txtlibrary.txttask.txtreferences/batch-files-and-functions.mdcygwin.mdmsys2.mdtools-and-resources.mdwindows-commands.mdwindows-subsystem-on-linux.md详细介绍
批处理文件
一套全面的技能,用于使用 cmd.exe 创建、编辑、调试和维护 Windows 批处理文件(.bat/.cmd)。适用于命令行工具开发、系统管理自动化、计划任务、文件操作脚本编写以及基于 PATH 的可执行脚本。
何时使用此技能
- 创建或编辑
.bat或.cmd文件 - 自动化 Windows 任务(文件操作、部署、备份)
- 构建面向 PATH 上
bin/文件夹的命令行工具 - 编写计划任务脚本(SCHTASKS、任务计划程序)
- 调试批处理脚本问题(变量展开、错误级别、引号)
- 将批处理脚本与外部工具集成(curl、git、Node.js、Python)
- 使用结构化模板搭建新的基于批处理的项目
前提条件
- 基于 Windows NT 的操作系统(Windows 7 或更高版本)
- cmd.exe(内置)
- 可选:PATH 上的
bin/目录,用于将脚本作为命令分发 - 可选:将 PATHEXT 配置为包含
.BAT;.CMD(Windows 上的默认值)
命令解释
cmd.exe 按顺序通过四个阶段处理每一行:
- 变量替换 —
%VAR%标记会被替换为环境变量值。%0–%9引用批处理参数。%*展开为所有参数。 - 引号和转义 — 脱字符
^转义特殊字符(& | < > ^)。引号可防止其中包含的特殊字符被解释。在批处理文件中,%%会生成一个字面量%。 - 语法解析 — 行被拆分为管道(
|)、复合命令(&、&&、||)以及括号分组( )。 - 重定向 —
>覆盖,>>追加,<读取输入,2>重定向 stderr,2>&1将 stderr 合并到 stdout,>NUL丢弃输出。
变量
环境变量
set _MY_VAR=Hello World
echo %_MY_VAR%
set _MY_VAR=
- 不带参数的
set会列出所有变量 set _PREFIX会列出以_PREFIX开头的变量=两侧不能有空格 —set name = val会将变量"name "设置为" val"
特殊变量
| 变量 | 值 |
|---|---|
%CD% | 当前目录 |
%DATE% | 系统日期(取决于区域设置) |
%TIME% | 系统时间 HH:MM:SS.mm |
%RANDOM% | 伪随机数 0–32767 |
%ERRORLEVEL% | 上一条命令的退出代码 |
%USERNAME% | 当前用户名 |
%USERPROFILE% | 当前用户配置文件路径 |
%TEMP% / %TMP% | 临时文件目录 |
%PATHEXT% | 可执行扩展名列表 |
%COMSPEC% | cmd.exe 的路径 |
使用 SETLOCAL / ENDLOCAL 限定作用域
setlocal
set _LOCAL_VAR=scoped value
endlocal
REM _LOCAL_VAR is no longer defined here
要从作用域块中返回值:
endlocal & set _RESULT=%_LOCAL_VAR%
延迟展开
括号块内的变量在解析时展开。使用延迟展开进行运行时求值:
setlocal EnableDelayedExpansion
set _COUNT=0
for /l %%i in (1,1,5) do (
set /a _COUNT+=1
echo !_COUNT!
)
endlocal
!VAR!在执行时展开(延迟)%VAR%在解析时展开(立即)
控制流
条件执行
if exist "output.txt" echo File found
if not defined _MY_VAR echo Variable not set
if "%_STATUS%"=="ready" (echo Go) else (echo Wait)
if %ERRORLEVEL% neq 0 echo Command failed
比较运算符:equ、neq、lss、leq、gtr、geq。使用 /i 进行不区分大小写的字符串比较。
复合命令
command1 & command2 & REM Always run both
command1 && command2 & REM Run command2 only if command1 succeeds
command1 || command2 & REM Run command2 only if command1 fails
FOR 循环
REM Iterate over a set of values
for %%i in (alpha beta gamma) do echo %%i
REM Numeric range: start, step, end
for /l %%i in (1,1,10) do echo %%i
REM Files in a directory
for %%f in (*.txt) do echo %%f
REM Recursive file search
for /r %%f in (*.log) do echo %%f
REM Directories only
for /d %%d in (*) do echo %%d
REM Parse command output
for /f "tokens=1,2 delims=:" %%a in ('ipconfig ^| findstr "IPv4"') do echo %%b
REM Parse file lines
for /f "usebackq tokens=*" %%a in ("data.txt") do echo %%a
GOTO 和标签
goto :main_logic
:usage
echo Usage: %~nx0 [options]
exit /b 1
:main_logic
echo Running main logic...
goto :eof
goto :eof 退出当前批处理或子例程。标签以 : 开头。
命令行参数
| 语法 | 值 |
|---|---|
%0 | 调用时的脚本名称 |
%1–%9 | 位置参数 |
%* | 所有参数(不受 SHIFT 影响) |
%~1 | 去掉外层引号的参数 1 |
%~f1 | 参数 1 的完整路径 |
%~d1 | 参数 1 的驱动器号 |
%~p1 | 参数 1 的路径(不含驱动器) |
%~n1 | 参数 1 的文件名(不含扩展名) |
%~x1 | 参数 1 的扩展名 |
%~dp0 | 批处理文件本身的驱动器和路径 |
%~nx0 | 批处理文件的文件名(含扩展名) |
%~z1 | 参数 1 的文件大小 |
%~$PATH:1 | 在 PATH 中搜索参数 1 |
参数解析模式
:parse_args
if "%~1"=="" goto :args_done
if /i "%~1"=="--help" goto :usage
if /i "%~1"=="--output" (
set "_OUTPUT_DIR=%~2"
shift
)
shift
goto :parse_args
:args_done
字符串处理
子字符串
set _STR=Hello World
echo %_STR:~0,5% & REM "Hello"
echo %_STR:~6% & REM "World"
echo %_STR:~-5% & REM "World"
echo %_STR:~0,-6% & REM "Hello"
搜索和替换
set _STR=Hello World
echo %_STR:World=Earth% & REM "Hello Earth"
echo %_STR:Hello=% & REM " World" (remove "Hello")
子字符串包含测试
if not "%_STR:World=%"=="%_STR%" echo Contains "World"
函数
函数使用标签、CALL 和 SETLOCAL/ENDLOCAL:
@echo off
call :greet "Jane Doe"
echo Result: %_GREETING%
exit /b 0
:greet
setlocal
set "_MSG=Hello, %~1"
endlocal & set "_GREETING=%_MSG%"
exit /b 0
call :label args调用函数exit /b从函数返回(而非从脚本返回)- 使用
endlocal & set技巧将值传出作用域块
算术运算
set /a 执行 32 位有符号整数算术运算:
set /a _RESULT=10 * 5 + 3
set /a _COUNTER+=1
set /a _REMAINDER=14 %% 3 & REM Use %% for modulo in batch files
set /a _BITS="255 & 0x0F" & REM Bitwise AND
支持的运算符:+ - * / %% ( ) 以及位运算 & | ^ ~ << >>。
支持十六进制(0xFF)和八进制(077)字面量。
错误处理
错误级别约定
0= 成功- 非零 = 失败(通常为
1)
mycommand.exe
if %ERRORLEVEL% neq 0 (
echo ERROR: mycommand failed with code %ERRORLEVEL%
exit /b %ERRORLEVEL%
)
快速失败模式
command1 || (echo command1 failed & exit /b 1)
command2 || (echo command2 failed & exit /b 1)
设置退出代码
exit /b 0 & REM Return success from a batch/function
exit /b 1 & REM Return failure
cmd /c "exit /b 42" & REM Set ERRORLEVEL to 42 inline
常用命令参考
文件操作
| 命令 | 用途 |
|---|---|
DIR | 列出目录内容 |
COPY | 复制文件 |
XCOPY | 支持子目录的扩展复制(旧版) |
ROBOCOPY | 支持重试、镜像、日志的可靠复制 |
MOVE | 移动或重命名文件 |
DEL | 删除文件 |
REN | 重命名文件 |
MD / MKDIR | 创建目录 |
RD / RMDIR | 删除目录 |
MKLINK | 创建符号链接或硬链接 |
ATTRIB | 查看或设置文件属性 |
TYPE | 打印文件内容 |
MORE | 分页显示文件 |
TREE | 显示目录结构 |
REPLACE | 用源文件替换目标位置的文件 |
COMPACT | 显示或设置 NTFS 压缩 |
EXPAND | 从 .cab 文件中提取 |
MAKECAB | 创建 .cab 归档 |
TAR | 创建或提取 tar 归档 |
文本搜索与处理
| 命令 | 用途 |
|---|---|
FIND | 搜索字面字符串 |
FINDSTR | 使用有限正则表达式搜索 |
SORT | 按字母顺序排序行 |
CLIP | 将管道输入复制到剪贴板 |
FC | 比较两个文件 |
COMP | 二进制文件比较 |
CERTUTIL | 编码/解码 Base64、计算哈希 |
系统信息
| 命令 | 用途 |
|---|---|
SYSTEMINFO | 完整系统配置 |
HOSTNAME | 显示计算机名 |
VER | Windows 版本 |
WHOAMI | 当前用户和组信息 |
TASKLIST | 列出正在运行的进程 |
TASKKILL | 终止进程 |
WMIC | WMI 查询(驱动器、操作系统、内存) |
SC | 服务控制(查询、启动、停止) |
DRIVERQUERY | 列出已安装的驱动程序 |
REG | 注册表操作(查询、添加、删除) |
SETX | 设置持久环境变量 |
网络
| 命令 | 用途 |
|---|---|
PING | 测试网络连通性 |
IPCONFIG | IP 配置 |
NSLOOKUP | DNS 查询 |
NETSTAT | 网络连接和端口 |
TRACERT | 跟踪到主机的路由 |
NET USE | 映射/断开网络驱动器 |
NET USER | 管理用户账户 |
NETSH | 网络配置实用工具 |
ARP | ARP 缓存管理 |
ROUTE | 路由表管理 |
CURL | HTTP 请求(Windows 10+) |
SSH | 安全 shell(Windows 10+) |
计划与自动化
| 命令 | 用途 |
|---|---|
SCHTASKS | 创建和管理计划任务 |
TIMEOUT | 等待 N 秒(Vista+) |
START | 异步启动程序 |
RUNAS | 以其他用户身份运行 |
SHUTDOWN | 关机或重启 |
FORFILES | 按日期查找文件并执行命令 |
Shell 实用工具
| 命令 | 用途 |
|---|---|
WHERE | 在 PATH 中定位可执行文件 |
DOSKEY | 创建命令宏 |
CHOICE | 提示单键输入 |
MODE | 配置控制台大小和端口 |
SUBST | 将文件夹映射到驱动器号 |
CHCP | 获取或设置控制台代码页 |
COLOR | 设置控制台颜色 |
TITLE | 设置控制台窗口标题 |
ASSOC / FTYPE | 文件类型关联 |
Shell 语法与表达式
用于分组的括号
括号将复合命令变为单个单元,以便进行重定向或条件执行:
(echo Line 1 & echo Line 2) > output.txt
if exist "data.csv" (
echo Processing...
call :process "data.csv"
) else (
echo No data found.
)
转义字符
脱字符 ^ 用于转义下一个字符:
echo Total ^& Summary & REM Outputs: Total & Summary
echo 100%% complete & REM Outputs: 100% complete (in batch)
echo Line one^
Line two & REM Caret escapes the newline
在管道符之后,需要使用三脱字符:echo x ^^^& y | findstr x
通配符
*匹配任意字符序列?匹配单个字符(在无句点的段末尾可匹配零个字符)
dir *.txt & REM All .txt files
ren *.jpeg *.jpg & REM Bulk rename
重定向摘要
command > file.txt & REM Overwrite stdout to file
command >> file.txt & REM Append stdout to file
command 2> errors.log & REM Redirect stderr
command > all.log 2>&1 & REM Merge stderr into stdout
command < input.txt & REM Read stdin from file
command > NUL 2>&1 & REM Discard all output
编写生产级批处理文件
标准脚本结构
@echo off
setlocal EnableDelayedExpansion
REM ============================================================
REM Script: example.bat
REM Purpose: Describe what this script does
REM ============================================================
call :main %*
exit /b %ERRORLEVEL%
:main
call :parse_args %*
if not defined _TARGET (
echo ERROR: --target is required. 1>&2
call :usage
exit /b 1
)
echo Processing: %_TARGET%
exit /b 0
:parse_args
if "%~1"=="" exit /b 0
if /i "%~1"=="--target" set "_TARGET=%~2" & shift
if /i "%~1"=="--help" call :usage & exit /b 0
shift
goto :parse_args
:usage
echo Usage: %~nx0 --target ^<path^> [--help]
echo.
echo Options:
echo --target Path to process (required)
echo --help Show this help message
exit /b 0
最佳实践
- 始终以
@echo off和setlocal开头 — 可防止输出杂乱,并避免变量泄漏到调用方。 - 在处理前验证输入 — 尽早检查必需参数和文件是否存在。使用
if not defined和if not exist。 - 为路径和变量加引号 — 使用
"%~1"和"%_MY_PATH%"以安全处理空格和特殊字符。 - 使用
exit /b而不是exit— 可避免关闭父控制台窗口。 - 返回有意义的退出代码 — 成功时使用
exit /b 0,特定失败时使用非零值。 - 使用
%~dp0表示脚本相对路径 — 确保脚本无论调用方的工作目录如何都能正常运行。 - 优先使用
ROBOCOPY而不是XCOPY— 更可靠,支持重试、镜像和日志记录。 - 在循环或括号块内修改变量时,使用
EnableDelayedExpansion。 - 将错误写入 stderr —
echo ERROR: message 1>&2可保持 stdout 干净,便于管道处理。 - 使用
REM添加注释 —::在FOR循环体内可能引发问题。
安全注意事项
- 切勿在批处理文件中存储凭据 — 请使用环境变量、凭据存储或提示输入。
- 验证用户输入 — 未加引号且包含
&、|或>的变量可能注入命令。请始终加引号:"%_USER_INPUT%"。 - 使用
SETLOCAL— 可防止变量值泄漏到父进程。 - 清理文件路径 — 在传递给
DEL、RD或ROBOCOPY之前验证路径,以防意外删除。 - 避免使用
SET /P处理敏感输入 — 输入可见且会存储在控制台历史中。尽可能使用专用的凭据工具。
调试与故障排除
| 技巧 | 方法 |
|---|---|
| 跟踪执行 | 移除 @echo off 或临时使用 @echo on |
| 逐步执行 | 在各部分之间添加 PAUSE |
| 检查错误级别 | 在每个命令后执行 echo Exit code: %ERRORLEVEL% |
| 检查变量 | 使用 set _MY_ 列出所有以 _MY_ 开头的变量 |
| 延迟展开问题 | ( ) 块内的变量未更新?启用 !VAR! 语法 |
FOR 循环中的 %% 与 % | 批处理文件中使用 %%i,命令行上使用 %i |
| SET 中的空格 | 使用 set name=value 而非 set name = value |
| 管道中的脱字符 | 在管道符之后,使用 ^^^ 转义特殊字符 |
| SET /A 中的括号 | 在 if 块内使用 ^( 和 ^) 转义,或使用引号 |
| 取模的双百分号 | 批处理文件中使用 set /a r=14 %% 3 |
跨平台与扩展工具
当批处理脚本达到其极限时,以下工具可扩展 cmd.exe 的能力:
| 工具 | 用途 |
|---|---|
| Cygwin | 在 Windows 上提供完整的 POSIX 环境(grep、sed、awk、ssh) |
| MSYS2 | 轻量级 Unix 工具和包管理器(pacman) |
| WSL | Windows Subsystem for Linux — 运行原生 Linux 二进制文件 |
| GnuWin32 | 作为原生 Windows 可执行文件的各个 GNU 实用工具 |
| PowerShell | 与 .NET 集成的现代 Windows 脚本 |
在需要以下情况时使用批处理:快速启动、简单文件操作、基于 PATH 的命令行工具或任务计划程序集成。对于复杂数据处理、REST API 或面向对象的脚本,请考虑使用 PowerShell 或 WSL。
CMD 键盘快捷键
| 快捷键 | 操作 |
|---|---|
Tab | 自动补全文件/文件夹名称 |
Up / Down | 浏览命令历史 |
F7 | 显示命令历史弹出窗口 |
F3 | 重复上一条命令 |
Esc | 清除当前行 |
Ctrl+C | 取消正在运行的命令 |
Alt+F7 | 清除命令历史 |
参考文件
references/ 文件夹包含详细文档:
| 文件 | 内容 |
|---|---|
tools-and-resources.md | Windows 工具、实用程序、包管理器、终端 |
batch-files-and-functions.md | 示例脚本、技巧、最佳实践链接 |
windows-commands.md | 全面的 A-Z Windows 命令参考 |
cygwin.md | Cygwin 用户指南和常见问题解答 |
msys2.md | MSYS2 安装、软件包和环境 |
windows-subsystem-on-linux.md | WSL 设置、命令和文档 |
资源模板
assets/ 文件夹包含批处理文件起始模板数据,但以文本文件形式提供:
| 模板 | 用途 |
|---|---|
executable.txt | 带参数解析的独立命令行工具 |
library.txt | 带可 CALL 标签的可复用函数库 |
task.txt | 计划任务 / 自动化脚本 |