fix(global_var): non-destructive .env writes; correct shell quoting

Three minimum-scope robustness fixes in .templates/00-global_var.sh:

1. shell_quote no longer doubles backslashes inside single quotes
   (e.g. 'C:\Users\test' was producing 'C:\\Users\\test' in injected
   scripts) and now uses the canonical '\'' escape for single quotes
   instead of the buggy '"'"' + trailing-space-trim form, which was
   mangling values containing apostrophes (e.g. "it's" -> "it' s").

2. /.env and /etc/environment are now patched in place: existing
   content from the upstream image and the system (PATH, LANG, etc.)
   is preserved and only the marked ADDON ENV block is replaced.
   Previously the whole files were overwritten, destroying upstream
   defaults.

3. Writing to /var/run/s6/container_environment is now best-effort
   (|| true) so a read-only mount on a single entry cannot abort the
   rest of the env injection under set -e.
This commit is contained in:
Claude
2026-05-18 13:32:17 +00:00
parent b41a9daec8
commit f00c8b9210

View File

@@ -82,11 +82,10 @@ dotenv_quote() {
}
shell_quote() {
# Single-quote for safe injection in shell code
local s="$1"
s="${s//\\/\\\\}"
s="${s//\'/\'\"\'\"\' }"
s="${s% }"
# Single-quote for safe injection in shell code.
# Inside single quotes only the single quote needs escaping ('->'\'').
# Do NOT escape backslashes: they are literal inside single quotes.
local s="${1//\'/\'\\\'\'}"
printf "'%s'" "$s"
}
@@ -166,9 +165,9 @@ export_var() {
# Runtime environment (no eval, safe for special chars)
export "$k=$v"
# S6 environment (preferred for services)
# S6 environment (preferred for services); best-effort, tolerate RO mounts
if [[ -d /var/run/s6/container_environment ]]; then
printf '%s' "$v" > "/var/run/s6/container_environment/$k"
printf '%s' "$v" > "/var/run/s6/container_environment/$k" || true
fi
# Queue for .env and /etc/environment (written once, idempotent)
@@ -219,18 +218,31 @@ done < <(
)
################################################################################
# Write .env and /etc/environment (idempotent: replace whole file content)
# Write .env and /etc/environment (idempotent: replace only our block,
# preserving any pre-existing content from the upstream image / system).
# Notes:
# - /.env is commonly used by apps expecting dotenv format
# - /etc/environment is read by PAM/system tooling; KEY="value" is acceptable
################################################################################
{
echo "$BLOCK_BEGIN"
cat "$KV_FILE"
echo "$BLOCK_END"
} > "$ENV_FILE.tmp"
mv "$ENV_FILE.tmp" "$ENV_FILE"
cp "$ENV_FILE" "$ETC_ENV_FILE"
update_env_file() {
local f="$1" tmp
tmp="$(mktemp_safe)"
if [[ -f "$f" ]]; then
awk -v b="$BLOCK_BEGIN" -v e="$BLOCK_END" '
$0==b { skip=1; next }
$0==e { skip=0; next }
!skip
' "$f" > "$tmp"
fi
{
echo "$BLOCK_BEGIN"
cat "$KV_FILE"
echo "$BLOCK_END"
} >> "$tmp"
mv "$tmp" "$f"
}
update_env_file "$ENV_FILE"
update_env_file "$ETC_ENV_FILE"
################################################################################
# Inject into scripts and shells (best-effort)