You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ublinux-init/ublinux/rc.preinit.d/53-language

214 lines
11 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
#
# Author: Dmitry Razumov <asmeron@ublinux.com>
# Copyright (c) 2021-2025 UBLinux <support@ublinux.com>
#
# Initial script for Linux UBLinux
# This script are launching before starting init from initrd script
# Current dir allways must be set to root (/)
# All system path must be relative, except initrd dirs
ENABLED=yes
[[ ${ENABLED} == "yes" ]] || exit 0
DEBUGMODE=no
PATH=.:/:/usr/bin:/usr/local/bin:/usr/local/sbin
[[ -d /usr/lib/ublinux ]] && { ROOTFS= ; CMD_CHROOT= ; } || { [[ -d /sysroot ]] && ROOTFS="/sysroot" || ROOTFS="."; CMD_CHROOT="chroot ${ROOTFS}"; }
SOURCE=${ROOTFS}/usr/lib/ublinux/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
SOURCE=${ROOTFS}/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
debug_mode "$0" "$@"
SYSCONF="${ROOTFS}${SYSCONF}"
SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/locale; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/keyboard; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
shopt -s extglob
# По сокращённому имени, вернуть полное имя, пример 'get_fullname_lang en' : en_US.UTF-8
get_fullname_lang(){
local LANG_NEW=$1
[[ -r ${ROOTFS}/usr/share/i18n/SUPPORTED ]] && local SUPPORTED=$(< ${ROOTFS}/usr/share/i18n/SUPPORTED)
# Из за того, что нет en_EN, а через груб прилетает просто en, то выбираем en_US.UTF-8
if [[ ${LANG_NEW} == @("en"|"") ]]; then
echo "en_US.UTF-8"
elif [[ ${SUPPORTED} =~ ($'\n'|^)"${LANG_NEW} ".*($'\n'|$) ]]; then
echo "${LANG_NEW}"
elif [[ ${SUPPORTED} =~ ($'\n'|^)"${LANG_NEW,,}_${LANG_NEW^^}.UTF-8 ".*($'\n'|$) ]]; then
echo "${LANG_NEW,,}_${LANG_NEW^^}.UTF-8"
elif [[ ${SUPPORTED} =~ ($'\n'|^)"${LANG_NEW,,}_${LANG_NEW^^} ".*($'\n'|$) ]]; then
echo "${LANG_NEW,,}_${LANG_NEW^^}"
elif [[ ${SUPPORTED} =~ ($'\n'|^)"${LANG_NEW}.UTF-8 ".*($'\n'|$) ]]; then
echo "${LANG_NEW}.UTF-8"
elif [[ ${SUPPORTED} =~ ($'\n'|^)("${LANG_NEW,,}_"[:A-Z:]+".UTF-8")" ".*($'\n'|$) ]]; then
echo "${BASH_REMATCH[2]}"
elif [[ ${SUPPORTED} =~ ($'\n'|^)("${LANG_NEW,,}_"[:A-Z:]+)" ".*($'\n'|$) ]]; then
echo "${BASH_REMATCH[2]}"
else
echo "en_US.UTF-8"
fi
}
exec_01_set_locale(){
# Не учитываем нстройку LOCALE из env ядра, при отсутствии в конфигурации
[[ -f ${SYSCONF}/locale && $(< ${SYSCONF}/locale) =~ (^|$'\n')LOCALE=\"?\'?([^$'\n'\"\']+)\"?\'?($'\n'|$) ]] && LOCALE=${BASH_REMATCH[2]} || LOCALE=
local LANG_NEW=$(cmdline_value lang)
# Если работает в initramf при загрузке и параметр ядра задан, то используем заданный параметр. Иначе из текущего окружения ${LANG}
[[ -n ${LANG_NEW} && -n ${ROOTFS} ]] && LANG_NEW="$(get_fullname_lang ${LANG_NEW})" || LANG_NEW=$(get_fullname_lang ${LANG})
if [[ ! -f ${SYSCONF}/locale ]] || [[ ! "${LOCALE}" =~ (^|,)${LANG_NEW}(,|$) ]]; then
LOCALE=${LOCALE:-en_US.UTF-8}
[[ ${LANG_NEW} == @("C.UTF-8"|"POSIX"|"C") ]] || LOCALE="${LOCALE:+${LOCALE},}${LANG_NEW}"
[[ -f ${SYSCONF}/locale ]] && sed "/^LOCALE=/d" -i "${SYSCONF}/locale"
echo "LOCALE=\"${LOCALE}\"" >> "${SYSCONF}/locale"
fi
# Проверка локалий в системе, и если не совпадают, то генерация
[[ -n ${FORCE_LOCARCHIVE} ]] && FORCEGEN=1
[[ -f ${ROOTFS}/usr/lib/locale/locale-archive ]] || FORCEGEN=1
LOCALE_CONF=${LOCALE//-/}; LOCALE_CONF=${LOCALE_CONF,,}; LOCALE_CONF=${LOCALE_CONF//,/$'\n'}; LOCALE_CONF=$(sort -fu <<< ${LOCALE_CONF})
LOCALE_SYSTEM=$(${CMD_CHROOT} localedef --list-archive | sort -fu); LOCALE_SYSTEM=${LOCALE_SYSTEM,,}
[[ "${LOCALE_CONF}" == "${LOCALE_SYSTEM}" ]] || FORCEGEN=1
if [[ -n ${FORCEGEN} ]]; then
# Комментируем все локализации
sed -E "s/^([^#]+)/#\1/g" -i ${ROOTFS}/etc/locale.gen
# Открываем комменарии нужных локалий
for SELECT_LOCALE in ${LOCALE//@(,|;)/ }; do
[[ -n ${SELECT_LOCALE} ]] || continue
sed -E "s/^#${SELECT_LOCALE} /${SELECT_LOCALE} /g" -i ${ROOTFS}/etc/locale.gen
done
# Генерируем локаль
${CMD_CHROOT} locale-gen &>/dev/null
fi
}
exec_02_set_lang(){
# Не учитываем нстройку LANG из env
[[ -f ${SYSCONF}/locale && $(< ${SYSCONF}/locale) =~ (^|$'\n')LANG=\"?\'?([^$'\n'\"\']+)\"?\'?($'\n'|$) ]] && LANG=${BASH_REMATCH[2]} || LANG=
local LANG_NEW=$(cmdline_value lang)
[[ -n ${LANG_NEW} && -n ${ROOTFS} ]] && LANG_NEW="$(get_fullname_lang ${LANG_NEW})" || LANG_NEW=$(get_fullname_lang ${LANG})
[[ ${LANG_NEW} == @("C.UTF-8"|"POSIX"|"C") ]] && LANG_NEW="en_US.UTF-8"
if [[ ! -f ${SYSCONF}/locale ]] || [[ ! "${LANG}" == "${LANG_NEW}" ]]; then
[[ -f ${SYSCONF}/locale ]] && sed "/^LANG=/d" -i "${SYSCONF}/locale"
echo "LANG=\"${LANG_NEW}\"" >> "${SYSCONF}/locale"
fi
# Проверка выбранного языка в системе, и если не совпадает, то устанавливаем
if [[ -w ${ROOTFS}/etc/locale.conf && ! $(< ${ROOTFS}/etc/locale.conf) =~ (^|$'\n')"LANG=${LANG_NEW}"($'\n'|$) ]] || [[ ! -f ${ROOTFS}/etc/locale.conf ]]; then
# Устанавливаем локаль
${CMD_CHROOT} env LANG="${LANG_NEW}" LANGUAGE="${LANG_NEW}" LC_CTYPE="${LANG_NEW}" LC_NUMERIC="${LANG_NEW}" \
LC_TIME="${LANG_NEW}" LC_COLLATE="${LANG_NEW}" LC_MONETARY="${LANG_NEW}" LC_MESSAGES="${LANG_NEW}" LC_PAPER="${LANG_NEW}" \
LC_NAME="${LANG_NEW}" LC_ADDRESS="${LANG_NEW}" LC_TELEPHONE="${LANG_NEW}" LC_MEASUREMENT="${LANG_NEW}" \
LC_IDENTIFICATION="${LANG_NEW}" locale > ${ROOTFS}/etc/locale.conf 2>/dev/null
[[ -n ${ROOTFS} ]] || set_lang_live
fi
#; unset LANG; source /etc/profile.d/locale.sh"
# Если имеются языкозависимые файлы, то копируем в корень
[[ -d ${ROOTFS}/usr/share/ublinux/langs/${LANG_NEW} ]] && cp -pfr ${ROOTFS}/usr/share/ublinux/langs/${LANG_NEW}/* ${ROOTFS}/
}
set_lang_live(){
if [[ $(readlink -fq /usr/bin/init 2>/dev/null) =~ "lib/systemd/systemd"$ ]]; then
systemctl daemon-reexec
fi
}
exec_03_set_vconsole(){
SOURCE=${SYSCONF}/locale; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
LANG=$(get_fullname_lang ${LANG})
[[ $(declare -p CONSOLE_FONT 2>/dev/null) =~ "declare -A" ]] || declare -A CONSOLE_FONT
[[ $(declare -p CONSOLE_FONT_MAP 2>/dev/null) =~ "declare -A" ]] || declare -A CONSOLE_FONT_MAP
[[ $(declare -p CONSOLE_FONT_UNIMAP 2>/dev/null) =~ "declare -A" ]] || declare -A CONSOLE_FONT_UNIMAP
[[ $(declare -p CONSOLE_KEYMAP 2>/dev/null) =~ "declare -A" ]] || declare -A CONSOLE_KEYMAP
[[ $(declare -p CONSOLE_KEYMAP_TOGGLE 2>/dev/null) =~ "declare -A" ]] || declare -A CONSOLE_KEYMAP_TOGGLE
# Зададим /etc/vconsole.conf
local SET_VCONSOLE="\
# Written by /ublinux/rc.preinit.d/53-language, read by manual.
# Use 'ubconfig set [locale] CONSOLE_FONT= CONSOLE_KEYMAP= CONSOLE_KEYMAP_TOGGLE=' to update this file.
"
local VCONSOLE_FILE="${ROOTFS}/etc/vconsole.conf"
if [[ -n ${CONSOLE_FONT} ]]; then
SET_VCONSOLE+="FONT=${CONSOLE_FONT}"$'\n'
elif [[ -n ${CONSOLE_FONT[${LANG%%_*}]} ]]; then
SET_VCONSOLE+="FONT=${CONSOLE_FONT[${LANG%%_*}]}"$'\n'
[[ -f ${SYSCONF}/keyboard ]] && sed "/^CONSOLE_FONT=/d" -i "${SYSCONF}/keyboard"
echo "CONSOLE_FONT=${CONSOLE_FONT[${LANG%%_*}]}" >> "${SYSCONF}/keyboard"
fi
if [[ -n ${CONSOLE_FONT_MAP} ]]; then
SET_VCONSOLE+="FONT_MAP=${CONSOLE_FONT_MAP}"$'\n'
elif [[ -n ${CONSOLE_FONT_MAP[${LANG%%_*}]} ]]; then
SET_VCONSOLE+="FONT_MAP=${CONSOLE_FONT_MAP[${LANG%%_*}]}"$'\n'
[[ -f ${SYSCONF}/keyboard ]] && sed "/^CONSOLE_FONT_MAP=/d" -i "${SYSCONF}/keyboard"
echo "CONSOLE_FONT_MAP=${CONSOLE_FONT_MAP[${LANG%%_*}]}" >> "${SYSCONF}/keyboard"
fi
if [[ -n ${CONSOLE_FONT_UNIMAP} ]]; then
SET_VCONSOLE+="FONT_UNIMAP=${CONSOLE_FONT_UNIMAP}"$'\n'
elif [[ -n ${CONSOLE_FONT_UNIMAP[${LANG%%_*}]} ]]; then
SET_VCONSOLE+="FONT_UNIMAP=${CONSOLE_FONT_UNIMAP[${LANG%%_*}]}"$'\n'
[[ -f ${SYSCONF}/keyboard ]] && sed "/^CONSOLE_FONT_UNIMAP=/d" -i "${SYSCONF}/keyboard"
echo "CONSOLE_FONT_UNIMAP=${CONSOLE_FONT_UNIMAP[${LANG%%_*}]}" >> "${SYSCONF}/keyboard"
fi
if [[ -n ${CONSOLE_KEYMAP} ]]; then
SET_VCONSOLE+="KEYMAP=${CONSOLE_KEYMAP}"$'\n'
elif [[ -n ${CONSOLE_KEYMAP[${LANG%%_*}]} ]]; then
SET_VCONSOLE+="KEYMAP=${CONSOLE_KEYMAP[${LANG%%_*}]}"$'\n'
[[ -f ${SYSCONF}/keyboard ]] && sed "/^CONSOLE_KEYMAP=/d" -i "${SYSCONF}/keyboard"
echo "CONSOLE_KEYMAP=${CONSOLE_KEYMAP[${LANG%%_*}]}" >> "${SYSCONF}/keyboard"
fi
if [[ -n ${CONSOLE_KEYMAP_TOGGLE} ]]; then
SET_VCONSOLE+="KEYMAP_TOGGLE=${CONSOLE_KEYMAP_TOGGLE}"$'\n'
elif [[ -n ${CONSOLE_KEYMAP_TOGGLE[${LANG%%_*}]} ]]; then
SET_VCONSOLE+="KEYMAP_TOGGLE=${CONSOLE_KEYMAP_TOGGLE[${LANG%%_*}]}"$'\n'
[[ -f ${SYSCONF}/keyboard ]] && sed "/^CONSOLE_KEYMAP_TOGGLE=/d" -i "${SYSCONF}/keyboard"
echo "CONSOLE_KEYMAP_TOGGLE=${CONSOLE_KEYMAP_TOGGLE[${LANG%%_*}]}" >> "${SYSCONF}/keyboard"
fi
[[ -z ${XKBLAYOUT} ]] || SET_VCONSOLE+="XKBLAYOUT=${XKBLAYOUT}"$'\n'
[[ -z ${XKBMODEL} ]] || SET_VCONSOLE+="XKBMODEL=${XKBMODEL}"$'\n'
[[ -z ${XKBVARIANT} ]] || SET_VCONSOLE+="XKBVARIANT=${XKBVARIANT}"$'\n'
[[ -z ${XKBOPTIONS} ]] || SET_VCONSOLE+="XKBOPTIONS=${XKBOPTIONS}"$'\n'
if [[ -n "${CONSOLE_FONT}${CONSOLE_KEYMAP}${CONSOLE_KEYMAP_TOGGLE}" ]]; then
if [[ -f "${VCONSOLE_FILE}" ]]; then
if [[ ! "$(< ${VCONSOLE_FILE})" == "${SET_VCONSOLE}" ]]; then
echo -n "${SET_VCONSOLE}" > "${VCONSOLE_FILE}"
[[ -n ${ROOTFS} ]] || set_vconsole_live
fi
else
echo -n "${SET_VCONSOLE}" > "${VCONSOLE_FILE}"
[[ -n ${ROOTFS} ]] || set_vconsole_live
fi
fi
}
set_vconsole_live(){
if [[ $(readlink -fq /usr/bin/init 2>/dev/null) =~ "lib/systemd/systemd"$ ]]; then
#systemctl --quiet start systemd-vconsole-setup.service
/usr/lib/systemd/systemd-vconsole-setup
else
#setfont ?
#loadkeys ?
true
fi
}
################
##### MAIN #####
################
# Если файл подключен как ресурс с функциями, то выйти
return 0 2>/dev/null && return 0
if [[ -z $@ ]]; then
while read -r FUNCTION; do
$"${FUNCTION##* }"
done < <(declare -F | grep "declare -f exec_")
else
FUNCTION=
while [[ $# -gt 0 ]]; do
#[[ -z ${1} ]] || { declare -f "${1}" &>/dev/null && FUNCTION+="; ${1}" || FUNCTION+=" '${1}'"; }
# Что-бы передавать пустые параметры как аргументы, нужно для соблюдения очередности и кол-ва, отключил [[ -z ${1} ]] ||
declare -f "${1}" &>/dev/null && FUNCTION+="; ${1}" || FUNCTION+=" '${1}'"
shift
done
eval ${FUNCTION#*; }
fi
true