|
1 | 1 | --- |
2 | | -description: "Batch/CMD scripting standards for Windows utilities" |
3 | | -applyTo: "**/*.cmd, **/*.bat" |
| 2 | +description: "CMD/Batch scripting standards for Windows batch file development" |
| 3 | +applyTo: "**/*.{bat,cmd}" |
4 | 4 | --- |
5 | 5 |
|
6 | | -# CMD/Batch Scripting Guidelines |
| 6 | +# CMD/Batch Scripting Standards |
7 | 7 |
|
8 | | -Instructions for writing minimal, reliable CMD/Batch scripts for Windows utilities and bootstrap tasks. |
| 8 | +<Goals> |
9 | 9 |
|
10 | | -## General Instructions |
| 10 | +- Fail fast: check errorlevel after commands |
| 11 | +- Performance: minimize overhead, batch operations |
| 12 | +- Clarity: descriptive names, consistent style |
11 | 13 |
|
12 | | -- Target `cmd.exe`; assume Windows 10+. |
13 | | -- Keep scripts **self-contained**; avoid external tools unless already standard on Windows. |
14 | | -- Use CRLF line endings; ASCII/UTF-8 without BOM. |
| 14 | +</Goals> |
15 | 15 |
|
16 | | -## Code Standards |
| 16 | +## Template |
17 | 17 |
|
18 | | -- Start with `@echo off` and `setlocal enabledelayedexpansion`. |
19 | | -- Quote all paths: `"%%~dp0"` for script dir; never parse `dir` output—use `for`. |
20 | | -- Use `if defined`/`if not defined` for presence checks; prefer `if /i` for case-insensitive compares. |
21 | | -- Avoid `%random%` for security decisions. |
22 | | -- Prefer `for %%V in (...) do` for iteration; avoid unbounded `goto` spaghetti—structure with labels and early exits. |
23 | | - |
24 | | -## Environment & Safety |
25 | | - |
26 | | -- Do not mutate global environment; end with `endlocal`. |
27 | | -- Validate prerequisites (admin, files) before actions. |
28 | | -- Use `%ERRORLEVEL%` checks after critical commands; `exit /b 1` on failure. |
| 18 | +```batch |
| 19 | +@echo off |
| 20 | +setlocal enabledelayedexpansion |
| 21 | +setlocal enableextensions |
| 22 | +``` |
29 | 23 |
|
30 | | -## I/O & Logging |
| 24 | +<Standards> |
31 | 25 |
|
32 | | -- Use `>nul 2>&1` to silence noisy commands; log to `%TEMP%\script.log` when debugging. |
33 | | -- Avoid `findstr` regex complexity; keep patterns simple and quoted. |
| 26 | +**Variables**: `set "name=value"` for assignment. `%var%` immediate, `!var!` delayed (in code blocks) |
| 27 | +**Control Flow**: `if exist`, `if "%errorlevel%"=="0"`, `for %%i in (...) do` |
| 28 | +**Subroutines**: `call :label`, `exit /b 0` to return |
| 29 | +**Errors**: `if errorlevel 1` or `command && echo Success || echo Failure` |
34 | 30 |
|
35 | | -## Examples |
| 31 | +</Standards> |
36 | 32 |
|
37 | | -### Good Example – Safe path handling |
| 33 | +```batch |
| 34 | +:: Subroutine with parameters |
| 35 | +call :process_file "input.txt" |
| 36 | +goto :eof |
38 | 37 |
|
39 | | -```bat |
40 | | -@echo off |
41 | | -setlocal enabledelayedexpansion |
42 | | -set "ROOT=%~dp0" |
43 | | -if not exist "%ROOT%data.txt" ( |
44 | | - echo Missing data.txt>&2 |
45 | | - exit /b 1 |
46 | | -) |
47 | | -for /f "usebackq delims=" %%L in ("%ROOT%data.txt") do ( |
48 | | - echo %%L |
49 | | -) |
50 | | -endlocal |
| 38 | +:process_file |
| 39 | +set "filename=%~1" |
| 40 | +set "fullpath=%~f1" |
| 41 | +echo Processing: %fullpath% |
| 42 | +exit /b 0 |
51 | 43 | ``` |
52 | 44 |
|
53 | | -### Bad Example – Unquoted paths, env pollution |
| 45 | +<Limitations> |
54 | 46 |
|
55 | | -```bat |
56 | | -echo on |
57 | | -set PATH=%CD%\tools;%PATH% |
58 | | -type data.txt |
59 | | -``` |
| 47 | +- No unquoted paths with spaces |
| 48 | +- No `%var%` inside code blocks (use `!var!` with delayed expansion) |
| 49 | +- No missing errorlevel checks |
| 50 | +- No environment modification without `setlocal` |
60 | 51 |
|
61 | | -## Validation |
| 52 | +</Limitations> |
62 | 53 |
|
63 | | -- Run in clean `cmd.exe` session. |
64 | | -- Test with spaces in paths. |
65 | | -- Confirm correct exit codes for success/failure. |
| 54 | +<Security> |
66 | 55 |
|
67 | | -## Maintenance |
| 56 | +- No hardcoded credentials |
| 57 | +- Input validation before use |
| 58 | +- Use `setlocal` to avoid polluting environment |
| 59 | +- Temporary files created securely |
68 | 60 |
|
69 | | -- Keep logic minimal; prefer moving complex flows to PowerShell. |
70 | | -- Re-test after Windows updates that may affect built-ins. |
| 61 | +</Security> |
0 commit comments