Development record
zsh reads `cd X Y` with two operands, and an option word it does not take (`cd -e X`, `cd -@ X`, `pushd -n X`), as the substitution form: it replaces the first word in the current directory's path with the second and enters the result, so the guard's script reader judges a script in one directory while zsh runs the one in another. Found by the Fable review of guard round 2 on 2026-10-11 (reproduced with zsh 5.9: `cd <p>/with-n/dir && pushd -n sub && pwd` prints <p>/withsub/dir); the cd forms predate that round, and round 2 made pushd -n read as staying put.
issueresolvedminoriss-2610111809142536
zsh reads cd X Y with two operands, and an option word it does not take (cd -e X, cd -@ X, pushd -n X), as the substitution form: it replaces the first word in the current directory's path with the second and enters the result, so the guard's script reader judges a script in one directory while zsh runs the one in another. Found by the Fable review of guard round 2 on 2026-10-11 (reproduced with zsh 5.9: cd <p>/with-n/dir && pushd -n sub && pwd prints <p>/withsub/dir); the cd forms predate that round, and round 2 made pushd -n read as staying put.
Frontmatter
| id | iss-2610111809142536 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | minor |
.abcd/work/issues/resolved/iss-2610111809142536-guard-misses-zsh-cd-substitution-form.md
open on GitHub ↗ · commit history ↗
mentions3
- iss-2610111815024967The guard's script reader treats `pushd` with no operand as going to HOME, but bash swaps the top two directories of the stack instead (zsh does the same unless an option sends it home), so the scripts that follow can be read in the wrong directory. Noticed by guard round 3 on 2026-10-11 while fixing the zsh cd substitution form (iss-2610111809142536); predates it.
- iss-2610111851225403After round 4 of the guard fixes (iss-2610111809142536), a cd whose option word has letters neither shell takes (`cd -x sub`) still leaves the directory unknown, so a following `bash s.sh` is allowed unread, while zsh reads the line as its substitution form (replacing `-x` in the current path with `sub`) when that string occurs in the path. Noted by guard round 4 on 2026-10-11; the same allow-unread held before round 3.
- iss-2610111855583968The guard's cd reader gives bash's reading no directory for three or more operands, but macOS /bin/bash 3.2.57 enters the first operand of `cd a b c` and exits 0 (verified 2026-10-11 with cd and pwd only), so a following `bash s.sh` runs the script in `a` while the guard leaves it unread. Same class as iss-2610111809142536; round 5 added the first operand for two operands only.