2 changed files with 67 additions and 35 deletions
@ -1,42 +1,74 @@ |
|||||||
#!/bin/env bash |
#!/bin/sh |
||||||
# ensure-locale.sh |
# ensure-locale.sh |
||||||
# Ensures a UTF-8 locale is available and exported (works safely on hosts and in containers). |
# Ensures a UTF-8 locale is available and active. |
||||||
|
# Works safely on hosts and pure/minimal Docker containers (Alpine, Debian, Ubuntu, RHEL). |
||||||
|
|
||||||
ensure_utf8_locale() { |
ensure_utf8_locale() { |
||||||
# If already UTF-8, nothing to do |
# 1. Prefer C.UTF-8 if available (standard in modern containers, avoids generation overhead) |
||||||
if locale | grep -qi 'utf-8'; then |
if command -v locale >/dev/null 2>&1 && locale -a 2>/dev/null | grep -qi '^C\.utf'; then |
||||||
|
export LANG=C.UTF-8 |
||||||
|
export LC_ALL=C.UTF-8 |
||||||
|
return 0 |
||||||
|
fi |
||||||
|
|
||||||
|
# 2. Check if current active charmap is ALREADY UTF-8 |
||||||
|
if command -v locale >/dev/null 2>&1; then |
||||||
|
if[ "$(locale charmap 2>/dev/null)" = "UTF-8" ]; then |
||||||
|
# Already UTF-8; ensure variables are cleanly exported for child processes |
||||||
|
export LANG="${LANG:-C.UTF-8}" |
||||||
|
export LC_ALL="${LC_ALL:-$LANG}" |
||||||
return 0 |
return 0 |
||||||
fi |
fi |
||||||
|
fi |
||||||
|
|
||||||
# If en_US.UTF-8 (or equivalent) exists, just use it |
# 3. Check for an existing en_US.UTF-8 |
||||||
if locale -a 2>/dev/null | grep -qi 'en_US\.utf8'; then |
if command -v locale >/dev/null 2>&1 && locale -a 2>/dev/null | grep -qi '^en_US\.utf'; then |
||||||
export LANG=en_US.UTF-8 |
export LANG=en_US.UTF-8 |
||||||
export LC_ALL=en_US.UTF-8 |
export LC_ALL=en_US.UTF-8 |
||||||
return 0 |
return 0 |
||||||
fi |
fi |
||||||
|
|
||||||
# Try to generate one if possible (Debian/Ubuntu) |
# 4. Try to generate en_US.UTF-8 (Debian/Ubuntu/Arch) |
||||||
if command -v locale-gen >/dev/null 2>&1; then |
if command -v locale-gen >/dev/null 2>&1; then |
||||||
echo "[ensure-locale] Generating en_US.UTF-8 locale..." |
echo "[ensure-locale] Generating en_US.UTF-8 locale..." >&2 |
||||||
locale-gen en_US.UTF-8 2>/dev/null || true |
|
||||||
# If update-locale exists, register it |
# Debian requires uncommenting the locale in /etc/locale.gen first |
||||||
command -v update-locale >/dev/null 2>&1 && update-locale LANG=en_US.UTF-8 || true |
if[ -w /etc/locale.gen ]; then |
||||||
|
sed -i 's/^# *\(en_US.UTF-8 UTF-8\)/\1/' /etc/locale.gen 2>/dev/null || true |
||||||
|
fi |
||||||
|
|
||||||
|
locale-gen en_US.UTF-8 >/dev/null 2>&1 || true |
||||||
|
|
||||||
|
if locale -a 2>/dev/null | grep -qi '^en_US\.utf'; then |
||||||
export LANG=en_US.UTF-8 |
export LANG=en_US.UTF-8 |
||||||
export LC_ALL=en_US.UTF-8 |
export LC_ALL=en_US.UTF-8 |
||||||
return 0 |
|
||||||
fi |
|
||||||
|
|
||||||
# Alpine / musl–based systems: locale-gen doesn't exist |
# Update system defaults if possible |
||||||
if [ -f /usr/lib/locale/locale-archive ] || grep -q musl /proc/self/maps 2>/dev/null; then |
if command -v update-locale >/dev/null 2>&1; then |
||||||
export LANG=C.UTF-8 |
update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 2>/dev/null || true |
||||||
export LC_ALL=C.UTF-8 |
fi |
||||||
return 0 |
return 0 |
||||||
fi |
fi |
||||||
|
fi |
||||||
|
|
||||||
# Fallback if nothing else works |
# 5. Fallback for pure Alpine / minimal musl containers without 'locale' installed |
||||||
export LANG=C.UTF-8 |
export LANG=C.UTF-8 |
||||||
export LC_ALL=C.UTF-8 |
export LC_ALL=C.UTF-8 |
||||||
} |
} |
||||||
|
|
||||||
# Call it immediately if script is sourced/run directly |
# Run the function |
||||||
ensure_utf8_locale |
ensure_utf8_locale |
||||||
|
|
||||||
|
# Persist the environment variables for future shell sessions (if running as root) |
||||||
|
if[ "$(id -u 2>/dev/null || echo 1)" = "0" ]; then |
||||||
|
if [ -d /etc/profile.d ] &&[ -w /etc/profile.d ]; then |
||||||
|
echo "export LANG=\"$LANG\"" > /etc/profile.d/00-locale.sh |
||||||
|
echo "export LC_ALL=\"$LC_ALL\"" >> /etc/profile.d/00-locale.sh |
||||||
|
fi |
||||||
|
fi |
||||||
|
|
||||||
|
# Allow script to be used as a Docker ENTRYPOINT wrapper |
||||||
|
# e.g., ./ensure-locale.sh python app.py |
||||||
|
if[ $# -gt 0 ]; then |
||||||
|
exec "$@" |
||||||
|
fi |
||||||
|
|||||||
Loading…
Reference in new issue