Skill 60 · Batch Script Progress
Subchapter 60.1
references/language-notes.mdMarkdown5 KBView on GitHub
Reuse an existing logger or reporting utility first. These notes describe standalone CLI streams; hosted functions and services may need their own logging contract.
print(..., file=sys.stderr, flush=True) for a small standalone script. Do not configure the root logger inside a reusable library.time.monotonic() for reporting intervals. -u or PYTHONUNBUFFERED can help with subprocess output, but verify the actual logger/stream path.KeyboardInterrupt and other control-flow exceptions out of a broad item-error catch.main and use raise SystemExit(main()) only at the executable entry point.The Python probe uses the standard library and never accesses external data.
Write-Output writes to the success stream, so it can corrupt returned objects or JSON. Use the existing information/error streams when the host contract supports them; for a standalone native CLI, [Console]::Error.WriteLine(...) and Flush() provide explicit stderr output.Write-Progress depends on the host and preferences. It may be invisible in CI or redirection; do not use it as the only evidence of progress.finally for cleanup where applicable, but do not promise a final summary after the host stops the pipeline. If graceful cancellation reporting is part of the contract, test the real cancellation path in each supported host; a simulated fixture does not establish it.[System.Diagnostics.Stopwatch] for elapsed intervals. Avoid a blocking Start-Sleep heartbeat in the same processing loop.-ErrorAction Stop at a specific cmdlet boundary when that matches the established policy; changing $ErrorActionPreference globally can change processing behavior.$LASTEXITCODE immediately after the native command. On Windows PowerShell 5.1, do not assume a nonzero native exit is a catchable terminating exception.exit only in a standalone entry point. A function/module should return its agreed result or raise its agreed error without terminating the host.The PowerShell probe is a standalone script compatible with Windows PowerShell 5.1 and PowerShell 7. Its cancellation case is simulated, not an OS-signal test.
console.log targets stdout; console.error targets stderr. For a stable record format, use the established logger or explicit stream writes.performance.now() or process.hrtime.bigint() for elapsed intervals. For redirected writes, respect backpressure and wait for drain when write returns false.process.exitCode after reporting instead of immediately calling process.exit(), which can truncate pending output.The Node.js probe has no dependencies and uses an async output emitter.
The verifier defaults to py -3 and powershell.exe on Windows, or python3 and pwsh elsewhere. Set BATCH_PYTHON to a Python executable path (not a shell command) to override the Python launcher; set BATCH_POWERSHELL similarly. Node.js uses the interpreter running the verifier.
On Windows the verifier passes -ExecutionPolicy Bypass only to its child PowerShell process so an unsigned local fixture can run. It does not change stored machine/user policy, and organization-enforced policy can still block it. Review the bundled fixture before running it; do not extend this setting to untrusted scripts.
Each probe accepts normal, mixed, partial-zero, empty, unknown, fail-fast, cancelled, or live. The fixture contract continues after failures except in fail-fast; codes are 0 for complete success, 1 for mixed/fail-fast, and 130 for simulated cancellation. The partial-zero fixture preserves a zero exit contract while reporting an honest partial outcome and one failed item. These are fixture choices, not imposed production exit codes. In live, the probe waits for one stdin line after the first progress notification so the verifier can prove pre-exit delivery without guessing a delay.