Second half of the purge (the first covered the persona, AGENTS.md, README.md, and the distillation of the per-host pages). Every remaining identifier is gone: hostname, both LAN addresses, and the Wi-Fi SSID. 34 count-checked substitutions across 22 files — indexes, tool/research pages, the inventory census, the changelog, one generated HTML report, and five managed skills. Facts kept, names dropped: a history entry keeps its four-page listing as a nameless summary, the syslog excerpts keep every timestamp and line, and the census keeps the .zcompdump rows (the zsh version stamps are the useful part, the hostname was not). Deliberately unchanged: install.sh's --host case list and the packages/<hostname>.pkgs filename, where the hostname is the lookup key. Left out of scope by Frank's call: agent/memories/** — past-session records the learn pipeline rewrites. kb-lint: 0 violations. Residual grep for the hostname, its two IPs, and the SSID across omp-docs/ and agent/managed-skills/: no hits.
1.8 KiB
1.8 KiB
name, description
| name | description |
|---|---|
| ssh-fish-host-remote-exec | Runbook for password-auth SSH exec/file-ship to fleet hosts whose login shell is fish (e.g. blankpad), avoiding the fish-parsing and heredoc-swallow traps |
When
Running remote commands or shipping files over SSH to a host whose login shell is fish (blankpad: user blank, reachable only as mDNS FQDN blankpad.local / 192.168.0.83 — bare hostname does not resolve from the workstation).
Procedure
- Auth:
SSHPASS='<pw>' sshpass -e ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no user@host '...'— password via env, never argv (ps-visible). - Remote exec:
ssh host 'cmd'pipes the command string to the login shell (fish). Bashisms likefor ... do,$?, heredoc markers fail at parse time on fish (Missing end to balance this for loop). Always wrap compound commands:ssh host 'bash -c "for b in a b c; do command -v $b || echo MISSING; done"'(escape inner$). - File shipping: never combine
cat > /remote/path <<EOFwith a trailingbash -sin the same ssh command —catdrains stdin, so the interpreter silently runs on empty stdin and prints nothing (silent no-op that looks like success). Ship real bytes via local-file stdin redirect:ssh host 'cat > /remote/path' < localfile, then verify byte-truth with md5sum on both ends. - Exit codes:
$?in an unquoted remote command is parsed by fish ($statusthere) — wrap in bash or drop the status echo; ssh's own exit code propagates to the caller anyway.
Why
Both traps fired during the 2026-09-09 blankpad dotfiles deploy: first probe attempt died on fish loop parsing; a cat > ship silently swallowed the heredoc that was meant for bash -s, deploying the wrong file bytes until md5-compared.