deploy-stack: add -n to ssh calls to prevent stdin slurp in loops

Without -n, ssh inherits the surrounding loop's stdin and consumes
the heredoc that feeds $changed / $deleted, silently truncating the
diff output to the first file only.
This commit is contained in:
2026-05-17 22:46:41 -07:00
parent 4b986f0b23
commit 9e9bdf9810
+8 -5
View File
@@ -134,7 +134,7 @@ for entry in "${PAIRS[@]}"; do
# Pre-create the remote dir. Without this, rsync against a nonexistent
# destination can fail in ways the dry-run doesn't surface cleanly.
remote_path="/opt/docker/$kind/$STACK/"
if ! ssh -o BatchMode=yes -o ConnectTimeout=10 "$TARGET" \
if ! ssh -n -o BatchMode=yes -o ConnectTimeout=10 "$TARGET" \
"mkdir -p '$remote_path'" 2>/dev/null; then
echo "error: could not create $remote_path on $TARGET (check perms / ssh)" >&2
exit 2
@@ -191,7 +191,7 @@ if [ "$any_change" -eq 0 ]; then
IFS='|' read -r kind _ _ <<<"$entry"
raw=${RAW_RSYNC_OUT_BY_KIND[$kind]:-}
remote_path="/opt/docker/$kind/$STACK/"
remote_count=$(ssh -o BatchMode=yes "$TARGET" \
remote_count=$(ssh -n -o BatchMode=yes "$TARGET" \
"find '$remote_path' -mindepth 1 -maxdepth 1 2>/dev/null | wc -l" \
2>/dev/null || echo "?")
printf ' %s: remote has %s entries, rsync itemize output:\n' "$kind" "$remote_count"
@@ -216,15 +216,18 @@ for entry in "${PAIRS[@]}"; do
printf '\n=== %s → %s ===\n' "$src" "$dest"
# ssh below runs with -n: without it, ssh slurps the loop's heredoc
# stdin ($changed / $deleted) and eats the remaining iterations,
# silently truncating the diff output to the first file only.
while IFS= read -r rel; do
[ -z "$rel" ] && continue
local_file="$src$rel"
remote_file="$remote_base/$rel"
divider
if ssh -o BatchMode=yes "$TARGET" "[ -f '$remote_file' ]" 2>/dev/null; then
if ssh -n -o BatchMode=yes "$TARGET" "[ -f '$remote_file' ]" 2>/dev/null; then
printf 'MODIFY %s\n' "$rel"
diff -u --label "a/$rel (remote)" --label "b/$rel (local)" \
<(ssh -o BatchMode=yes "$TARGET" "cat '$remote_file'" 2>/dev/null) \
<(ssh -n -o BatchMode=yes "$TARGET" "cat '$remote_file'" 2>/dev/null) \
"$local_file" || true
else
printf 'ADD %s\n' "$rel"
@@ -239,7 +242,7 @@ for entry in "${PAIRS[@]}"; do
divider
printf 'DELETE %s\n' "$rel"
diff -u --label "a/$rel (remote)" --label /dev/null \
<(ssh -o BatchMode=yes "$TARGET" "cat '$remote_file'" 2>/dev/null) \
<(ssh -n -o BatchMode=yes "$TARGET" "cat '$remote_file'" 2>/dev/null) \
/dev/null || true
done <<<"$deleted"
done