From 8d60d48bd07a7686d246a418496f6747362e35b7 Mon Sep 17 00:00:00 2001 From: maro Date: Wed, 26 Aug 2026 02:12:24 +0200 Subject: [PATCH] Fix .env writer: quote values so shell metacharacters don't break source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit deploy.sh sources .env directly as bash (`set -a; source .env`), but setup.sh wrote raw unquoted values. The default SMTP_FROM ("ANOUMA ") contains `<`/`>`, which bash parses as redirections, failing with "syntax error near unexpected token `newline'" on every deploy. Both scripts' env_set now write double-quoted values with backslashes/quotes escaped — valid for both `source` and Docker Compose's env_file parsing (which strips matching quotes). Co-Authored-By: Claude Sonnet 5 --- deploy.sh | 12 +++++++++--- setup.sh | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/deploy.sh b/deploy.sh index ec0e14f..926a8cf 100755 --- a/deploy.sh +++ b/deploy.sh @@ -61,13 +61,19 @@ trap 'rm -f "$LOCK_FILE"' EXIT # .env helpers — same idempotent read/write approach as setup.sh. # --------------------------------------------------------------------------- env_get() { grep -E "^$1=" .env 2>/dev/null | tail -n1 | cut -d'=' -f2- || true; } +# Quoted the same way as setup.sh's env_set — this file is `source`d as a +# bash script below, so an unquoted value with shell metacharacters would +# break parsing. env_set() { - local key="$1" value="$2" + local key="$1" value="$2" escaped quoted + escaped="${value//\\/\\\\}" + escaped="${escaped//\"/\\\"}" + quoted="\"${escaped}\"" if grep -qE "^$key=" .env; then local tmp; tmp="$(mktemp)" - awk -v k="$key" -v v="$value" 'BEGIN{FS=OFS="="} $1==k{$0=k "=" v} {print}' .env > "$tmp" && mv "$tmp" .env + awk -v k="$key" -v v="$quoted" 'BEGIN{FS=OFS="="} $1==k{$0=k "=" v} {print}' .env > "$tmp" && mv "$tmp" .env else - printf '%s=%s\n' "$key" "$value" >> .env + printf '%s=%s\n' "$key" "$quoted" >> .env fi } diff --git a/setup.sh b/setup.sh index 9c3851a..b1376e3 100755 --- a/setup.sh +++ b/setup.sh @@ -263,13 +263,23 @@ env_get() { $SUDO grep -E "^$1=" "$ENV_FILE" 2>/dev/null | tail -n1 | cut -d'=' # passing, never re-interpolated into a nested shell string) so arbitrary # characters in $value — quotes, backslashes, anything a typed SMTP/registry # password might contain — can never break quoting or be misinterpreted. +# +# The value is written double-quoted, with backslashes and double quotes +# escaped: deploy.sh later `source`s this file as a bash script, so an +# unquoted value containing shell metacharacters (e.g. the default +# SMTP_FROM="ANOUMA ", whose `<`/`>` are redirections) breaks +# with "syntax error near unexpected token `newline'". Quoting also works +# fine for Docker Compose's own env_file parsing, which strips matching +# surrounding quotes. env_set() { - local key="$1" value="$2" tmp + local key="$1" value="$2" tmp escaped + escaped="${value//\\/\\\\}" + escaped="${escaped//\"/\\\"}" tmp="$(mktemp)" if $SUDO test -f "$ENV_FILE"; then $SUDO grep -vE "^${key}=" "$ENV_FILE" > "$tmp" 2>/dev/null || true fi - printf '%s=%s\n' "$key" "$value" >> "$tmp" + printf '%s="%s"\n' "$key" "$escaped" >> "$tmp" $SUDO cp "$tmp" "$ENV_FILE" rm -f "$tmp" }