3 changed files with 87 additions and 58 deletions
@ -1,74 +1,84 @@ |
|||||||
#!/bin/sh |
#!/bin/sh |
||||||
# ensure-locale.sh |
# ensure-locale.sh |
||||||
# Ensures a UTF-8 locale is available and active. |
# Ensures UTF-8 locale is generated and persisted system-wide. |
||||||
# Works safely on hosts and pure/minimal Docker containers (Alpine, Debian, Ubuntu, RHEL). |
# Safe, idempotent. Requires root (or sudo) for system-wide changes. |
||||||
|
# Usage: |
||||||
|
# sudo ./ensure-locale.sh |
||||||
|
# ./ensure-locale.sh cmd args # entrypoint wrapper |
||||||
|
|
||||||
ensure_utf8_locale() { |
_locale_log() { printf '[ensure-locale] %s\n' "$*" >&2; } |
||||||
# 1. Prefer C.UTF-8 if available (standard in modern containers, avoids generation overhead) |
|
||||||
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 |
_utf8_active() { |
||||||
if command -v locale >/dev/null 2>&1; then |
_eff="${LC_ALL:-${LC_CTYPE:-$LANG}}" |
||||||
if[ "$(locale charmap 2>/dev/null)" = "UTF-8" ]; then |
case "$_eff" in |
||||||
# Already UTF-8; ensure variables are cleanly exported for child processes |
*[Uu][Tt][Ff]8* | *[Uu][Tt][Ff]-8*) return 0 ;; |
||||||
export LANG="${LANG:-C.UTF-8}" |
esac |
||||||
export LC_ALL="${LC_ALL:-$LANG}" |
return 1 |
||||||
return 0 |
} |
||||||
fi |
|
||||||
fi |
_locale_exists() { |
||||||
|
locale -a 2>/dev/null | grep -qi "$1" |
||||||
|
} |
||||||
|
|
||||||
# 3. Check for an existing en_US.UTF-8 |
ensure_locale_generated() { |
||||||
if command -v locale >/dev/null 2>&1 && locale -a 2>/dev/null | grep -qi '^en_US\.utf'; then |
if _locale_exists '^en_US\.utf'; then |
||||||
export LANG=en_US.UTF-8 |
_locale_log "en_US.UTF-8 already generated." |
||||||
export LC_ALL=en_US.UTF-8 |
return 0 |
||||||
return 0 |
fi |
||||||
fi |
|
||||||
|
|
||||||
# 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 |
_locale_log "locale-gen not found; skipping generation." |
||||||
echo "[ensure-locale] Generating en_US.UTF-8 locale..." >&2 |
return 1 |
||||||
|
fi |
||||||
|
|
||||||
|
if [ "$(id -u)" != "0" ]; then |
||||||
|
_locale_log "Not root; cannot generate locale. Run with sudo." |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
|
||||||
|
_locale_log "Generating en_US.UTF-8..." |
||||||
|
[ -w /etc/locale.gen ] && |
||||||
|
sed -i 's/^# *\(en_US.UTF-8 UTF-8\)/\1/' /etc/locale.gen 2>/dev/null || true |
||||||
|
locale-gen en_US.UTF-8 >/dev/null 2>&1 |
||||||
|
update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 2>/dev/null || true |
||||||
|
_locale_log "Generated en_US.UTF-8." |
||||||
|
} |
||||||
|
|
||||||
# Debian requires uncommenting the locale in /etc/locale.gen first |
ensure_zshenv() { |
||||||
if[ -w /etc/locale.gen ]; then |
_zshenv=/etc/zsh/zshenv |
||||||
sed -i 's/^# *\(en_US.UTF-8 UTF-8\)/\1/' /etc/locale.gen 2>/dev/null || true |
_marker="en_US.UTF-8" |
||||||
fi |
|
||||||
|
|
||||||
locale-gen en_US.UTF-8 >/dev/null 2>&1 || true |
if [ "$(id -u)" != "0" ]; then |
||||||
|
_locale_log "Not root; cannot write $_zshenv. Run with sudo." |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
|
||||||
if locale -a 2>/dev/null | grep -qi '^en_US\.utf'; then |
if [ -f "$_zshenv" ] && grep -q "$_marker" "$_zshenv" 2>/dev/null; then |
||||||
export LANG=en_US.UTF-8 |
_locale_log "$_zshenv already contains UTF-8 locale settings." |
||||||
export LC_ALL=en_US.UTF-8 |
return 0 |
||||||
|
fi |
||||||
|
|
||||||
# Update system defaults if possible |
_locale_log "Writing locale exports to $_zshenv..." |
||||||
if command -v update-locale >/dev/null 2>&1; then |
mkdir -p "$(dirname $_zshenv)" |
||||||
update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 2>/dev/null || true |
cat >>"$_zshenv" <<'EOF' |
||||||
fi |
|
||||||
return 0 |
|
||||||
fi |
|
||||||
fi |
|
||||||
|
|
||||||
# 5. Fallback for pure Alpine / minimal musl containers without 'locale' installed |
# UTF-8 locale — added by ensure-locale.sh |
||||||
export LANG=C.UTF-8 |
export LANG=en_US.UTF-8 |
||||||
export LC_ALL=C.UTF-8 |
export LC_ALL=en_US.UTF-8 |
||||||
|
EOF |
||||||
|
_locale_log "Done. Open a new shell or run: exec zsh" |
||||||
} |
} |
||||||
|
|
||||||
# Run the function |
ensure_locale_generated |
||||||
ensure_utf8_locale |
ensure_zshenv |
||||||
|
|
||||||
# Persist the environment variables for future shell sessions (if running as root) |
# Export for the current session too |
||||||
if[ "$(id -u 2>/dev/null || echo 1)" = "0" ]; then |
if _locale_exists '^en_US\.utf' && ! _utf8_active; then |
||||||
if [ -d /etc/profile.d ] &&[ -w /etc/profile.d ]; then |
export LANG=en_US.UTF-8 |
||||||
echo "export LANG=\"$LANG\"" > /etc/profile.d/00-locale.sh |
export LC_ALL=en_US.UTF-8 |
||||||
echo "export LC_ALL=\"$LC_ALL\"" >> /etc/profile.d/00-locale.sh |
|
||||||
fi |
|
||||||
fi |
fi |
||||||
|
|
||||||
# Allow script to be used as a Docker ENTRYPOINT wrapper |
# Entrypoint wrapper: ./ensure-locale.sh python app.py |
||||||
# e.g., ./ensure-locale.sh python app.py |
if [ $# -gt 0 ]; then |
||||||
if[ $# -gt 0 ]; then |
exec "$@" |
||||||
exec "$@" |
|
||||||
fi |
fi |
||||||
|
|||||||
@ -0,0 +1,19 @@ |
|||||||
|
#!/bin/env bash |
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" |
||||||
|
|
||||||
|
# ubuntu |
||||||
|
sudo apt update -y |
||||||
|
sudo apt install -y \ |
||||||
|
jq \ |
||||||
|
ripgrep \ |
||||||
|
fd-find \ |
||||||
|
zoxide \ |
||||||
|
fzf-lua |
||||||
|
|
||||||
|
cd /tmp |
||||||
|
curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim-linux-x86_64.tar.gz |
||||||
|
sudo rm -rf /opt/nvim-linux-x86_64\nsudo tar -C /opt -xzf nvim-linux-x86_64.tar.gz |
||||||
|
rm nvim-linux-x86_64.tar.gz |
||||||
|
sudo ln -sf /opt/nvim-linux-x86_64/bin/nvim /usr/bin/nvim |
||||||
|
nvim --version |
||||||
Loading…
Reference in new issue