Cross-Platform Shell Execution Engine (pkg/shellcmd)
pkg/shellcmd converts configured command strings into safe, cross-platform argv argument lists for process execution across POSIX (macOS, Linux) and Windows systems.
1. Motivation
Scheduler jobs, callback hooks, and router actions often contain shell one-liners with pipelines, output redirections, environment variables, and quoted arguments with whitespace:
tee -a "log.jsonl" >/dev/null && zqk feed steer -m "mission started"
If such a string is split naively on whitespace (strings.Fields), the shell operators (>, &&) and quoted words become literal arguments passed to tee, corrupting the command and littering files across the workspace.
pkg/shellcmd solves this by:
- Detecting if the command string requires shell interpretation (
NeedsShell). - If plain (no shell metacharacters), splitting on whitespace to bypass shell overhead.
- If shell syntax is required, delegating to the operating system's native shell processor.
- Failing closed (returning
nil) on blank/whitespace-only input.
2. Windows Behavior & Considerations
When running on Windows (runtime.GOOS == "windows"):
-
Shell Resolution (
ResolveShell): - Checks the%COMSPEC%environment variable (typicallyC:\Windows\System32\cmd.exe). - If%COMSPEC%is unset or empty, falls back tocmd.exe. - Uses the termination switch/c(cmd.exe /c "<command>"). -
Windows Shell Metacharacters: The
shellMetaCharsdetector includes Windows-specific syntax:
%for environment variable expansion (%USERPROFILE%,%PATH%)^for escape sequences incmd.exe- In addition to standard POSIX characters (
|,&,;,<,>,(,),$,`,\,",',*,?,[,#,\n)
- Important Limitations on Windows:
- POSIX Syntax Incompatibility:
cmd.exedoes not support POSIX idioms such asexport VAR=val,set -e,set -o pipefail, single-quoted strings'literal', or/dev/null(Windows usesNUL). - POSIX Shim Execution: Commands written for POSIX shells that are executed undercmd.exewill fail with syntax errors unless run inside a POSIX environment (such as Git Bashbash.exe, WSL, or MSYS2). - Path Separators: Backslash vs forward-slash handling in command arguments is respected as authored.