#!/usr/bin/env bash # # Author: Dmitry Razumov # Copyright (c) 2021-2025 UBLinux # # 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 NEWLANG=$1 [[ -r ${ROOTFS}/usr/share/i18n/SUPPORTED ]] && local SUPPORTED=$(< ${ROOTFS}/usr/share/i18n/SUPPORTED) # Из за того, что нет en_EN, а через груб прилетает просто en, то выбираем en_US.UTF-8 [[ ${NEWLANG} == "en" ]] && NEWLANG="en_US.UTF-8" if [[ ${SUPPORTED} =~ ($'\n'|^)"${NEWLANG} ".*($'\n'|$) ]]; then echo "${NEWLANG}" elif [[ ${SUPPORTED} =~ ($'\n'|^)"${NEWLANG,,}_${NEWLANG^^}.UTF-8 ".*($'\n'|$) ]]; then echo "${NEWLANG,,}_${NEWLANG^^}.UTF-8" elif [[ ${SUPPORTED} =~ ($'\n'|^)"${NEWLANG,,}_${NEWLANG^^} ".*($'\n'|$) ]]; then echo "${NEWLANG,,}_${NEWLANG^^}" elif [[ ${SUPPORTED} =~ ($'\n'|^)"${NEWLANG}.UTF-8 ".*($'\n'|$) ]]; then echo "${NEWLANG}.UTF-8" elif [[ ${SUPPORTED} =~ ($'\n'|^)("${NEWLANG,,}_"[:A-Z:]+".UTF-8")" ".*($'\n'|$) ]]; then echo "${BASH_REMATCH[2]}" elif [[ ${SUPPORTED} =~ ($'\n'|^)("${NEWLANG,,}_"[:A-Z:]+)" ".*($'\n'|$) ]]; then echo "${BASH_REMATCH[2]}" else echo "en_US.UTF-8" fi } exec_01_set_locale(){ local NEWLANG=$(cmdline_value lang) if [[ -n ${NEWLANG} && -n ${ROOTFS} ]]; then LANG="$(get_fullname_lang ${NEWLANG})" [[ ${LOCALE} =~ (^|,)${LANG}(,|$) ]] || LOCALE+=",${LANG}" [[ -f ${SYSCONF}/locale ]] && sed "/^LOCALE=/d" -i "${SYSCONF}/locale" echo "LOCALE=${LOCALE}" >> "${SYSCONF}/locale" else LANG=$(get_fullname_lang ${LANG}) [[ ${LOCALE} =~ (^|,)${LANG}(,|$) ]] || LOCALE+=",${LANG}" 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(){ SOURCE=${SYSCONF}/locale; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null local NEWLANG=$(cmdline_value lang) if [[ -n ${NEWLANG} && -n ${ROOTFS} ]]; then LANG="$(get_fullname_lang ${NEWLANG})" [[ -f ${SYSCONF}/locale ]] && sed "/^LANG=/d" -i "${SYSCONF}/locale" echo "LANG=${LANG}" >> "${SYSCONF}/locale" else LANG=$(get_fullname_lang ${LANG}) fi # Проверка выбранного языка в системе, и если не совпадает, то устанавливаем if [[ -r ${ROOTFS}/etc/locale.conf && ! $(< ${ROOTFS}/etc/locale.conf) =~ (^|$'\n')"LANG=${LANG}"($'\n'|$) ]]; then # Устанавливаем локаль ${CMD_CHROOT} env LANG="${LANG}" LANGUAGE="${LANG}" LC_CTYPE="${LANG}" LC_NUMERIC="${LANG}" \ LC_TIME="${LANG}" LC_COLLATE="${LANG}" LC_MONETARY="${LANG}" LC_MESSAGES="${LANG}" LC_PAPER="${LANG}" \ LC_NAME="${LANG}" LC_ADDRESS="${LANG}" LC_TELEPHONE="${LANG}" LC_MEASUREMENT="${LANG}" \ LC_IDENTIFICATION="${LANG}" 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} ]] && cp -pfr ${ROOTFS}/usr/share/ublinux/langs/${LANG}/* ${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