Выглядит проблема так:
И присутствует в текущем релизе Ubuntu 15.10 и в бета-версии Ubuntu 16.04. Тем, кому интересно узнать причины проблемы и как можно её решить — прошу под хабракат.
Лирическое вступление
Всё началось с Clonezilla. Это такой Linux Live CD/USB с программой Clonezilla для копирования дисков. Делаю, я, значит, себе загрузочную флешку с различными утилитами и, по-возможности, включаю русификацию, там где это возможно, так как хочу поделиться флешкой с коллегами, а они не все хорошо владеют английским. Только-что закончил настраивать GParted Live. Думаю, что всё должно быть похоже — оба дистрибутива поддерживают live-config. Задаю параметры для русификации — добавляю к параметрам ядра следующие значения:
locales=ru_RU.UTF-8
keyboard-layouts=us,ru
keyboard-options=grp:ctrl_shift_toggle,lctrl_shift_toggle
Первый параметр задаёт язык, на котором система будет с нами общаться и кодировку. Второй параметр задаёт раскладки клавиатур, которые мы будем использовать. И третий задаёт способ переключения раскладок клавишами CTRL+SHIFT. На самом деле, язык и раскладку можно выбрать после запуска Clonezilla, но нельзя выбрать две раскладки и способ переключения — будет только русская или только английская клавиатура. Эти параметры корректно отработали в GParted Live и я ожидаю такого же поведения от Clonezilla. Но… после загрузки вместо русских символов отображаются чёрные квадратики:
Вспоминаю, что Clonezilla предлагает две ветки дистрибутива: стабильная базируется на Debian и альтернативная на Ubuntu. Альтернативная содержит несвободное ПО, такое как прошивка (firmware) некоторого оборудования (например, WiFi-карт), поэтому, я скачал её — для большей универсальности.
Ради хохмы качаю стабильную версию, основанную на Debian, запускаю с русской локалью — всё отображается корректно.
Подозрения падают на родительский дистрибутив — Ubuntu 15.10. Как раз у меня такой, думаю я и переключаюсь на текстовую консоль (Ctrl+Alt+F1) и запускаю `date`:
На-ка, говорит Убунта.
Поворот не туда
Здравый смысл подсказывает — бери стабильную Clonezilla и работай дальше. Но. Впереди выходные, Dota 2 меня «отпустила», а память подсказывает что проблемы с локализацией текстовой консоли в Ubuntu существуют давно, решаются с переменным успехом и хочется всё-таки разобраться.
Гуглим проблему и обнаруживаем, что с подобным сталкиваются начиная с Ubuntu 11.10. Есть несколько решений разной степени полезности, самое популярное — включить опцию FRAMEBUFFER=y для initramfs и пересобрать initrd командой update-initramfs. Со словами «только бы не думать, и наша возьмет!» добавляю строку FRAMEBUFFER=y в конец файла initramfs.conf, обновляю образ initrd и перезагружаюсь:
echo FRAMEBUFFER=y | sudo tee -a /etc/initramfs-tools/initramfs.conf
sudo update-initramfs -u
sudo reboot
После перезагрузки изменений нет, всё те-же квадратики вместо кириллицы. На форумах многие так же жалуются на то, что этот способ им не помог.
Начнём сначала
Откатил все изменения назад, пораскинул мозгами. За настройку консоли в Ubuntu отвечает пакет console-setup, который хранит настройки в /etc/default/console-setup и применяет их через команду setupcon. Настройки можно изменить просто отредактировав файл или через dpkg-reconfigure console-setup. Проверяем настройки консоли:
cat /etc/default/console-setup
ACTIVE_CONSOLES="/dev/tty[1-6]"
CHARMAP="UTF-8"
CODESET="guess"
FONTFACE="Fixed"
FONTSIZE="8x16"
В текстовой консоли даём команду setupcon. Даже на глаз видно, что шрифт изменился и теперь консоль отображает кириллицу:
Значит, в системе есть всё для отображения кириллицы, но при загрузке эти настройки не применяются. Посмотрим, что находится внутри пакета console-setup:
mkdir console-setup && cd console-setup
apt-get download console-setup
dpkg-deb -R *.deb ./
Помимо уже упомянутых двух файлов (console-setup и setupcon) интерес представляет файл console-font.conf, устанавливаемый в /etc/init/. Этот файл представляет из себя скрипт systemd, системы начальной загрузки linux, заменившей system v init. Посмотрим на содержимое:
# console-font - set console font
#
# Set the console font, in case the similar udev rule races with Plymouth
# and thus fails to do it.
description "set console font"
start on starting plymouth-splash
task
exec /lib/udev/console-setup-tty fbcon
Судя по заголовку и описанию это похоже на то, что надо — установка шрифта консоли при загрузке системы. Задача по установке шрифта перекладывается на скрипт /lib/udev/console-setup-tty. Приведу самые интересные части этого скрипта:
...
# Based on setupcon, but stripped down for use in a udev rule.
...
. /etc/default/console-setup
...
if [ "$1" = fbcon ]; then
# Technically we have to wait for /dev/tty[1-6] to appear; but these are
# created in vty_init, so I think it will always be early enough. If
# I'm wrong, then the -w test will fail and we end up with the wrong
# fonts on some virtual consoles; the user can run setupcon to fix it.
for console in $ACTIVE_CONSOLES; do
if [ -w "$console" ]; then
setup_font "$console"
fi
done
else
if [ -w "$1" ]; then
setup_unicode "$1"
setup_font "$1"
setup_keyboard_mode "$1"
fi
fi
Я пока пропустил все функции, которые определены внутри скрипта, чтобы обратить внимание на самое важное. Первый комментарий говорит, что скрипт основан на setupcon, но урезан, чтобы соответствовать правилу udev. Допустим. Ниже идёт включение файла настроек (. /etc/default/console-setup). Дальше идёт проверка первого параметра, переданного скрипту, как раз с таким параметром (fbcon) скрипт вызывается из /etc/init/сonsole-font.conf. Для каждой активной консоли (указаны в /etc/default/console-setup) делается проверка на возможность записи в неё и, для каждой консоли вызывается функция setup_font. При этом, автор скрипта пишет, что к моменту вызова скрипта консоли должны быть созданы, а если нет, то тест на запись в консоль не сработает и эта консоль останется не настроенной. А пользователь сам может вызвать setupcon потом. Возьмём это на заметку и рассмотрим функцию setup_font из файла /lib/udev/console-setup-tty:
setup_font () {
# Set the font and ACM. setfont will silently do nothing for a console
# in graphics mode.
SETFONT_ARGS=
if [ "$FONT" ]; then
FONT="/etc/console-setup/${FONT##*/}"
FONT="${FONT%.gz}"
else
FONT="/etc/console-setup/$CODESET-$FONTFACE$FONTSIZE.psf"
fi
if [ -f "$FONT" ]; then
SETFONT_ARGS="${SETFONT_ARGS:+$SETFONT_ARGS }$FONT"
fi
if [ "$ACM" ]; then
ACM="/etc/console-setup/${ACM##*/}"
ACM="${ACM%.gz}"
else
ACM="/etc/console-setup/$CHARMAP.acm"
fi
if [ -f "$ACM" ]; then
SETFONT_ARGS="${SETFONT_ARGS:+$SETFONT_ARGS }-m $ACM"
fi
if [ "$SETFONT_ARGS" ]; then
setfont -C "$1" $SETFONT_ARGS
fi
}
Вооот. Вот он косяк. Переменная $FONT у нас не задана, срабатывает строка
FONT="/etc/console-setup/$CODESET-$FONTFACE$FONTSIZE.psf"
Напомню настройки консоли:
CHARMAP="UTF-8"
CODESET="guess"
FONTFACE="Fixed"
FONTSIZE="8x16"
Переменные $CODESET, $FONTFACE, $FONTSIZE берутся напрямую из файла конфигурации и больше не изменяются. Выходит, что FONT="/etc/console-setup/guess-Fixed8x16.psf". Посмотрим, какие шрифты у нас есть в /etc/console-setup/:
ls /etc/console-setup/*.psf*
/etc/console-setup/Uni2-Fixed16.psf.gz
Таким образом, скрипт неправильно обрабатывет CODESET=«guess». Он должен был «догадаться» об используемом наборе символов. Так же неправильно обрабатывается FONTSIZE=«8x16», вероятно, должна оставаться бОльшая из цифр или последняя цифра. Но и это ещё не всё… Наш шрифт сжат и имеет расширение .gz. Как оказалось, команда setfont, которая вызывается дальше, сама добавит расширение .gz если не найдёт файл *.psf и загрузит шрифт. Но вот проверка на наличие файла с именем $FONT
if [ -f "$FONT" ];
не пройдёт и, переменная $SETFONT_ARGS останется пустой — соответственно, блок, непосредственно устанавливающий шрифт,
if [ "$SETFONT_ARGS" ]; then
setfont -C "$1" $SETFONT_ARGS
fi
не будет выполнен.
Зная эту информацию, мы можем подстроиться под систему и вручную задать $CODESET=«Uni2» и
$FONTSIZE=«16» или, вместо этого задать переменную $FONT=«Uni2-Fixed16.psf». Кроме того, нам нужно файл шрифта распаковать:
cd /etc/console-setup
sudo gunzip -k Uni2-Fixed16.psf.gz
После перезагрузки шрифт будет установлен, но при смене шрифта через dpkg-reconfigure console-setup нам придётся опять вносить исправления вручную.
Продолжаем разговор
Вспоминаем про скрипт setupcon, который был упомянут в комментариях и на котором базируется /lib/udev/console-setup-tty. Смотрим, что у него внутри:
# setupcon -- setup the font and keyboard on the Linux console
…
###########################################################################
### INITIALIZATION AND DEFAULT VALUES
###########################################################################
…
# CODESET
[ "$CODESET" != guess ] || CODESET=''
if [ -z "$CODESET" ]; then
case "$CHARMAP" in
UTF-8) CODESET=Uni2;;
ARMSCII-8) CODESET=Armenian ;;
CP1251) CODESET=CyrSlav ;;
CP1255) CODESET=Hebrew ;;
CP1256) CODESET=Arabic ;;
GEORGIAN-ACADEMY) CODESET=Georgian ;;
GEORGIAN-PS) CODESET=Georgian ;;
IBM1133) CODESET=Lao ;;
ISIRI-3342) CODESET=Arabic ;;
ISO-8859-1) CODESET=Lat15 ;;
ISO-8859-2) CODESET=Lat2 ;;
ISO-8859-3) CODESET=Lat38 ;;
ISO-8859-4) CODESET=Lat7 ;; # sometimes Lat15
ISO-8859-5) CODESET=CyrSlav ;;
ISO-8859-6) CODESET=Arabic ;;
ISO-8859-7) CODESET=Greek ;;
ISO-8859-8) CODESET=Hebrew ;;
ISO-8859-9) CODESET=Lat15 ;;
ISO-8859-10) CODESET=Lat15 ;;
ISO-8859-11) CODESET=Thai ;;
ISO-8859-13) CODESET=Lat7 ;;
ISO-8859-14) CODESET=Lat38 ;;
ISO-8859-15) CODESET=Lat15 ;;
ISO-8859-16) CODESET=Lat2 ;;
KOI8-R) CODESET=CyrKoi ;;
KOI8-U) CODESET=CyrKoi ;;
TIS-620) CODESET=Thai ;;
VISCII) CODESET=Vietnamese ;;
*)
if [ "$do_font" ]; then
echo Unsupported charmap $CHARMAP >&2
exit 1
fi
;;
esac
if [ "$kernel" = freebsd ]; then
# 512 character fonts are not supported on FreeBSD
case "$CODESET" in
Uni*|Vietnamese|Arabic|Ethiopian) CODESET=Lat15 ;;
esac
fi
fi
…
# FONTSIZE
if [ -z "$FONTSIZE" -o "$FONTSIZE" = guess ]; then
FONTSIZE=16
fi
case "$FONTSIZE" in
8x*)
FONTSIZE=${FONTSIZE#*x}
;;
*x8)
FONTSIZE=${FONTSIZE%x*}
;;
*x*)
a=${FONTSIZE%x*}
b=${FONTSIZE#*x}
if [ "$a" -lt "$b" ]; then
FONTSIZE=${b}x${a}
fi
;;
esac
Скрипт содержит код для Linux и FreeBSD, всё что относится к BSD можно смело пропускать. Я оставил только самое интересное — обработку $CODESET и $FONTSIZE. Как раз в этом скрипте есть обработка ситуации, когда $CODESET не задана или имеет значение 'guess'. В этом случае, $CODESET принимает значение, зависящее от $CHARMAP. В нашем случае $CODESET=Uni2.
$FONTSIZE так же проверяется на незаданное значение или 'guess' и жестко устанавливается в '16', если это так. Если $FONTSIZE задан как 8x* или *x8, то знак 'x' и восьмёрка отбрасывается, и остаётся только одна цифра (высота шрифта). Например, было '8x14' — останется '14', а от '15x8' останется '15'. Если $FONTSIZE задан как две цифры '*x*':
*x*)
a=${FONTSIZE%x*}
b=${FONTSIZE#*x}
(a — первая цифра, b — вторая), то бОльшая цифра переставляется вперёд:if [ "$a" -lt "$b" ]; then
FONTSIZE=${b}x${a}
fi
Например, было '10x20' — стало '20x10', а '22x11' меняться не будет. Посмотрим, как называются шрифты, доступные в системе:
ls /usr/share/consolefonts/
…
/usr/share/consolefonts/Uni2-Fixed13.psf.gz
/usr/share/consolefonts/Uni2-Fixed14.psf.gz
…
/usr/share/consolefonts/Uni2-Terminus22x11.psf.gz
/usr/share/consolefonts/Uni2-Terminus24x12.psf.gz
…
/usr/share/consolefonts/Uni2-TerminusBold28x14.psf.gz
/usr/share/consolefonts/Uni2-TerminusBold32x16.psf.gz
…
Сходится. Теперь, если добавить такую обработку параметров $CODESET и $FONTSIZE в скрипт /lib/udev/console-setup-tty, а так же добавить в этот скрипт проверку на существование сжатого файла *.psf.gz (а заодно и *.acm.gz):
if [ -f "$FONT" ] || [ -f "$FONT.gz" ]; then
SETFONT_ARGS="${SETFONT_ARGS:+$SETFONT_ARGS }$FONT"
fi
…
if [ -f "$ACM" ] || [ -f "$ACM.gz" ]; then
SETFONT_ARGS="${SETFONT_ARGS:+$SETFONT_ARGS }-m $ACM"
fi
то скрипт отработает правильно.
Тёплые потроха
Продолжаем потрошить скрипты. Ищем, откуда (из какого пакета) растут ноги у /lib/udev/console-setup-tty:
sudo apt-get install apt-file
apt-file update
apt-file search /lib/udev/console-setup-tty
keyboard-configuration: /lib/udev/console-setup-tty
Скачиваем и распаковываем пакет keyboard-configuration:
apt-get download keyboard-configuration
dpkg-deb -R keyboard-configuration_1.108ubuntu9_all.deb ./
Смотрим, в каких скриптах используется файл настроек /etc/default/console-setup:
grep -rm 1 etc/default/console-setup ./
./lib/udev/console-setup-tty:. /etc/default/console-setup
./usr/share/doc/keyboard-configuration/README.Debian:(/etc/default/keyboard and /etc/default/console-setup) perhaps it will
./usr/share/apport/package-hooks/source_console-setup.py: report, '/etc/default/console-setup', 'ConsoleSetup')
./usr/share/initramfs-tools/scripts/panic/console_setup:[ -r /etc/default/console-setup ] || exit 0
./usr/share/initramfs-tools/scripts/init-top/console_setup:[ -r /etc/default/console-setup ] || exit 0
./usr/share/initramfs-tools/hooks/console_setup:[ -r /etc/default/console-setup ] || exit 0
./DEBIAN/config:OLDCONFIGFILE=/etc/default/console-setup
Из них интерес представляют только:
./lib/udev/console-setup-tty
./usr/share/initramfs-tools/scripts/panic/console_setup
./usr/share/initramfs-tools/scripts/init-top/console_setup
./usr/share/initramfs-tools/hooks/console_setup
Все они содержат код, похожий на тот, что мы разобрали выше — из /lib/udev/console-setup-tty, без корректной обработки $CODESET и $FONTSIZE. А эти два файла
./usr/share/initramfs-tools/scripts/panic/console_setup
./usr/share/initramfs-tools/scripts/init-top/console_setup
отличаюся только одной строкой:
OPTION=FRAMEBUFFER
Знакомая опция, подумал я… Три интересующих нас скрипта расположены в папке initramfs-tools. Пакет initramfs-tools отвечает за сборку образа initrd, который загружается в память при загрузке ядра и используется им в тот момент, пока не доступна основная файловая система. В initrd обычно содержатся модули ядра, необходимые для его работы на нашем оборудовании и для подключения файловых систем, а так же, скрипты инициализации и их конфигурационные файлы. Собирается образ скриптом update-initramfs, который, в итоге, вызывает скрипт mkinitramfs. Как всегда, посмотрим что внутри у mkinitramfs:
…
CONFDIR="/etc/initramfs-tools"
...
. "${CONFDIR}/initramfs.conf"
…
# add existant boot scripts
for b in $(cd /usr/share/initramfs-tools/scripts/ && find . -regextype posix-extended -regex '.*/[[:alnum:]\._-]+$' -type f); do
option=$(sed '/^OPTION=/!d;$d;s/^OPTION=//;s/[[:space:]]*$//' "/usr/share/initramfs-tools/scripts/${b}")
[ -z "${option}" ] || eval test -n \"\${$option}\" -a \"\${$option}\" != \"n\" || continue
[ -d "${DESTDIR}/scripts/$(dirname "${b}")" ] || mkdir -p "${DESTDIR}/scripts/$(dirname "${b}")"
cp -p "/usr/share/initramfs-tools/scripts/${b}" "${DESTDIR}/scripts/$(dirname "${b}")/"
done
Здесь всё выглядит довольно сложно, я попробую показать с примерами. Этот блок проходит по всем файлам в /usr/share/initramfs-tools/scripts/ и подпапках, и ищет внутри них строку, содержащую 'OPTION='. Например, в файле /usr/share/initramfs-tools/scripts/init-top/console_setup есть строка
OPTION=FRAMEBUFFER
Если 'OPTION' отсутствует или не задана — файл (скрипт) копируется в initrd. Если 'OPTION' присутствует, берут значение этой опции как имя переменной и проверяют установлена ли она и не равна ли 'n'. В нашем примере проверяется переменная $FRAMEBUFFER. Эту переменную мы устанавливали в FRAMEBUFFER=y в самом начале, в файле initramfs.conf. Так как само значение переменной FRAMEBUFFER в скриптах, относящихся к setup-console не используется, оно действует как триггер и можем задать ему любое значение, не обязательно 'y'. Даже 'no' или 'none' отработает так же как 'y'. Итак, если FRAMEBUFFER определена и не равна 'n', скрипт будет помещён в образ initrd. Таких скриптов 8:
cd /usr/share/initramfs-tools/scripts
grep -rl FRAMEBUFFER ./
./init-premount/brltty
./panic/plymouth
./init-bottom/plymouth
./init-top/keymap
./init-top/framebuffer
./init-top/console_setup
./init-top/brltty
./init-top/plymouth
Этими скриптами запускается и настраивается фреймбуфер (framebuffer) — грубо говоря, текстовая консоль переводится в графический режим. После этого появляется возможность отрисовывать в ней изображения и нестандартные шрифты. Вот как раз console_setup и устанавливает шрифт для консоли. Вероятно, из-за того, что пользователь может выбрать нестандартный шрифт, этот скрипт привязан к запуску фреймбуфера и без установленого параметра 'FRAMEBUFFER=y' не добавляется в initrd.
Таким образом, при активации фреймбуфера, так же будет происходить настройка консоли с установкой шрифта, но на более раннем этапе.
Но вернёмся к нашим скриптам из keyboard-configuration
./lib/udev/console-setup-tty
./usr/share/initramfs-tools/scripts/panic/console_setup
./usr/share/initramfs-tools/scripts/init-top/console_setup
./usr/share/initramfs-tools/hooks/console_setup
Скрипт …/init-top/console_setup копируется в образ initrd при установленном параметре 'FRAMEBUFFER=y'.
Скрипт …/panic/console_setup копируется в initrd всегда, т. к. не содержит заданную переменную 'OPTION'. Скрипты из каталога panic вызываются функцией panic из скрипта init (который включает функции из файла /usr/share/initramfs-tools/scripts/functions). Сама же функция panic вызывается в случае, когда скрипт инициализации init не может продолжить выполнение (не найдена корневая файловая система и т.п.). Значит, скрипт…/panic/console_setup предназначен для настройки консоли в режиме panic, чтобы вывести сообщения в родной для пользователя кодировке.
Скрипт …/hooks/console_setup вызывается из скрипта mkinitramfs, при создании образа initrd:
...
CONFDIR="/etc/initramfs-tools"
...
run_scripts_optional /usr/share/initramfs-tools/hooks
run_scripts_optional "${CONFDIR}"/hooks
Этот скрипт занимается тем, что копирует файлы, необходимые для настройки консоли (файл шрифта, таблицу перекодировки шрифта (acm) и файл раскладки клавиатуры (keymap)) в initrd. Соответственно, даже если мы исправим init-top/console_setup, но забудем внести изменения в hooks/console_setup, настройка консоли на этом этапе не произойдёт из-за отсутствия необходимых файлов.
Вносим исправления
Теперь, зная каким образом происходит настройка консоли и где допущены ошибки, можно внести правки в код. Качаем исходный код пакета keyboard-configuration, так же, скачаем все зависимости для пересборки пакета:
apt-get source keyboard-configuration
sudo apt-get build-dep keyboard-configuration
Но вместо keyboard-configuration у нас скачался пакет console-setup, из которого, как оказалось собирается несколько deb-файлов, в том числе console-setup и keyboard-configuration. Заходим в корень исходников, и смотрим в каких файлах используется переменная FONT:
grep -rl \$FONT ./
./debian/font-switch
./debian/console-setup.config
./debian/console-setup.postinst
./debian/console-setup.initramfs-hook
./debian/console-setup.initramfs-top
./console-setup-tty
./setupcon
После их изучения, понятно что нам интересны только
./debian/console-setup.initramfs-hook
./debian/console-setup.initramfs-top
./console-setup-tty
./setupcon
Первые три надо исправить, а последний нам послужит донором, так как содержит код, обрабатывающий $CODESET и $FONTSIZE.
Исправление заключается в добавлении следующего кода:
# CODESET
[ "$CODESET" != guess ] || CODESET=''
if [ -z "$CODESET" ]; then
case "$CHARMAP" in
UTF-8) CODESET=Uni2;;
ARMSCII-8) CODESET=Armenian ;;
CP1251) CODESET=CyrSlav ;;
CP1255) CODESET=Hebrew ;;
CP1256) CODESET=Arabic ;;
GEORGIAN-ACADEMY) CODESET=Georgian ;;
GEORGIAN-PS) CODESET=Georgian ;;
IBM1133) CODESET=Lao ;;
ISIRI-3342) CODESET=Arabic ;;
ISO-8859-1) CODESET=Lat15 ;;
ISO-8859-2) CODESET=Lat2 ;;
ISO-8859-3) CODESET=Lat38 ;;
ISO-8859-4) CODESET=Lat7 ;; # sometimes Lat15
ISO-8859-5) CODESET=CyrSlav ;;
ISO-8859-6) CODESET=Arabic ;;
ISO-8859-7) CODESET=Greek ;;
ISO-8859-8) CODESET=Hebrew ;;
ISO-8859-9) CODESET=Lat15 ;;
ISO-8859-10) CODESET=Lat15 ;;
ISO-8859-11) CODESET=Thai ;;
ISO-8859-13) CODESET=Lat7 ;;
ISO-8859-14) CODESET=Lat38 ;;
ISO-8859-15) CODESET=Lat15 ;;
ISO-8859-16) CODESET=Lat2 ;;
KOI8-R) CODESET=CyrKoi ;;
KOI8-U) CODESET=CyrKoi ;;
TIS-620) CODESET=Thai ;;
VISCII) CODESET=Vietnamese ;;
*) ;;
esac
fi
# FONTSIZE
if [ -z "$FONTSIZE" -o "$FONTSIZE" = guess ]; then
FONTSIZE=16
fi
case "$FONTSIZE" in
8x*)
FONTSIZE=${FONTSIZE#*x}
;;
*x8)
FONTSIZE=${FONTSIZE%x*}
;;
*x*)
a=${FONTSIZE%x*}
b=${FONTSIZE#*x}
if [ "$a" -lt "$b" ]; then
FONTSIZE=${b}x${a}
fi
;;
esac
в каждый из файлов, после подключения конфигурационного файла и проверок, например:
...
[ -r /etc/default/console-setup ] || exit 0
. /etc/default/console-setup
[ "$ACTIVE_CONSOLES" ] || exit 0
# CODESET
[ "$CODESET" != guess ] || CODESET=''
if [ -z "$CODESET" ]; then
...
Так же нужно добавить проверку на сжатый файлы:
if [ -f "$FONT" ] || [ -f "$FONT.gz" ]; then
SETFONT_ARGS="${SETFONT_ARGS:+$SETFONT_ARGS }$FONT"
fi
…
if [ -f "$ACM" ] || [ -f "$ACM.gz" ]; then
SETFONT_ARGS="${SETFONT_ARGS:+$SETFONT_ARGS }-m $ACM"
fi
После внесения правок можем пересобрать пакет — заходим в корень исходников и выполняем:
dpkg-buildpackage -uc -b
Устанавливаем исправленный пакет и запрещаем ему обновления, иначе Ubuntu заменит его текущим (неисправленным) пакетом из репозитория:
sudo dpkg -i keyboard-configuration_*.deb
sudo apt-mark hold keyboard-configuration
Всё, теперь при загрузке ОС будет корректно настраиваться текстовая консоль.
Скачать патч и исправленный пакет можно на странице с багрепортом на ланчпаде. Там же можно увеличить приоритет ошибки, зарегистрировавшись и нажав «This bug affects me».
Комментарии (81)
av0000
07.04.2016 15:08+6Вот жеж! И не лень было докопаться до истоков! Решительно плюсую.
Меня хватает только на `dpkg-reconfigure console-setup` и вызов `setupcon` где-то в /etc/rc.local или даже в ~/.bashrc.
Кстати, убунта этим страдает как минимум с 10.04 — ещё жив под рукой сервер, на котором проводились подобные «пляски с бубном»Rondo
07.04.2016 15:268.04 тоже страдала, раньше — не припомню, но setupcon гуглился уже тогда легко, видимо проблема так же стара, как убунта
denis_l_eryomin
07.04.2016 15:30-11Просто ад какой-то. В слаке всё гораздо проще. Дайте неграм Linux и они его извратят и усложнят до невозможности. Убунту второй виндовс и не нужен ни под каким соусом. Даже мята не спасает, один хрен дерьмом тянет.
PavelSandovin
07.04.2016 15:39-14Я очень люблю Linux, но к сожалению, в актуальных версиях Windows нет таких проблем. Так что это даже не второй Windows. Это просто Ubuntu.
merlin-vrn
07.04.2016 17:06+13В актуальных версиях Windows не просто дофига таких проблем, там их ещё больше, чем было в неактуальных. Ибо если во времена 9x было ansi и oem, читай windows-1251 и ibm866, то теперь ещё появились разные вариации юникода, в том числе utf-8 с bom (некорректный — в utf-8 не должно быть bom).
Регулярно приходится отлавливать хрень в сообщении об ошибке в непонятно какой кодировке. Бывает, что в соседних строках, из которых составляется одна общая — разные кодировки. А ошибки эти надо решать.
А апофеозом ситуации является IBM Lotus Domino, который мало того, что сам выдаёт сообщения в SMTP-сессию не в латинице (чего нельзя делать по стандарту — кодировка и язык на этом этапе не согласовываются), так ещё и некоторые системные сообщения выдаёт прям в SMTP-сессию в той кодировке, в которой ему отдала винда, то есть, не в той, в которой говорил сам. Когда его ставишь в линуксе, такой порнографии не видно.PavelSandovin
07.04.2016 18:33Кто выдает эти сообщения об ошибках? Приложения, идущие в составе дистрибутива Windows или приложения сторонних разработчиков, как Lotus Domino?
merlin-vrn
07.04.2016 21:18Сообщения системные, типа «файл не найден». В Bacula, например, нет таких сообщений вообще.
То есть, возвращает ИМЕННО система.
Вообще, я вас обязан расстроить: чтобы это исправить, придётся отказаться от обратной совместимости и перевести всё — cmd тоже — на рельсы utf-8. И тогда куча уже имеющихся бинарников будет отображать кракозябры, но зато проблем типа «запустил dir > file.txt, открыл блокнотом — вижу кракозябры» не будет.PavelSandovin
08.04.2016 10:25Ладно-ладно, хотел я вам ответить тут вчера, но моя новенькая Windows 10 на ноутбуке выдала красивый такой обновленный BSOD, когда я писал комментарий. Ждем Ubuntu 16.04. Посмотрим что будет в ней хорошего и какие недоделки останутся :)
hdfan2
07.04.2016 18:42> в utf-8 не должно быть bom
Почему? А как его отличить от различных вариантов UTF-16?EvilFox
07.04.2016 20:47+1У UTF-16 всегда есть сигнатура. Тем не менее для UTF-8 иногда полезно иметь BOM, ибо для обнаружения что перед нами документ в UTF-8 те ещё костыли в редакторах используют, которые не всегда срабатывают (если например в поток вкрались вдруг местами одиночные байты типа \x00 и прочий мусор).
Cheater
08.04.2016 12:54+1Пользователь должен явно сообщать приложению, читающему поток символов, какую кодировку использовать.
Как пользователь эту кодировку узнает — его проблемы, но класть подсказки внутрь самого текста (BOM) — одна из худших идей ever.
merlin-vrn
11.04.2016 08:41+1Никак. Её просто не должно быть в интерфейсах. Просто, все интерфейсы, абсолютно все, должны быть в одной кодировке.
И UTF-16 не подходит уже потому, что она не имеет определённого порядка байтов. UTF-8 же его имеет (всегда «сетевой порядок»), поэтому BOM в ней быть не может. Какой может быть byte order mark в кодировке, в которой byte order однозначно зафиксирован?
barker
07.04.2016 19:07+4некорректный — в utf-8 не должно быть bom
Правильно будет: «в utf-8 может не быть bom». utf-8 с BOM — не является некорректным. BOM — это просто конкретный юникодный символ 0xFEFF, стандарт не мешает его использовать в utf-8 (хотя не рекомендуется), так же как не заставляет использовать в других кодировках юникода.
ComodoHacker
08.04.2016 11:17Вас не затруднит объяснить, причем тут негры?
igorp1024
08.04.2016 13:18Очевидно, вот причём:
ubuntu |oo'boontoo| Ubuntu is an ancient African word meaning 'humanity to others'. It also means 'I am what I am because of who we all are'. The Ubuntu operating system brings the spirit of Ubuntu to the world of computers.
poxu
07.04.2016 15:36Может вопрос не совсем в тему, но тем не менее. Я когда последний раз на убунту смотрел, там переключение раскладки по Alt+Shift настроить нельзя было. И пару релизов ещё не работало оно. Что там сейчас? Починили?
Sild
07.04.2016 15:48+3Да, починили.
SabMakc
07.04.2016 16:05А проблема с гаснущим NumLock при смене раскладки еще наблюдается, не знаете?
Судя по launchpad задача открыта…prostofilya
07.04.2016 17:30+1Не знал о таком) сейчас проверил на 14.04 — да, гаснет.
SabMakc
07.04.2016 17:48+2К сожалению, проблема не в том, что гаснет, а в том, что потом цифровой блок ведет себя рандомно в разных приложениях.
Где-то включен, где-то выключен, а где-то нечто среднее. Например, 2/4/6/8 работают как стрелки, а остальные — как цифры.Sykoku
08.04.2016 13:24Предположу, что не сохраняется состояние регистра клавиатуры. Если у Вас есть доп клавиша «Fn», то тогда и выскакивают такие прелести.
SabMakc
08.04.2016 13:56Использую самую стандартную полноразмерную PS/2 клавиатуру на 104 клавиши…
Есть подозрение на беспроводную мышь Logitech M570 (у нее навороченный приемник с возможностью подключения нескольких устройств). Надо будет попробовать откатит патченные пакеты и выдернуть мышь.
Duke_kz
07.04.2016 20:44А еще вопрос аналогичный, можно ли сейчас в убунте назначить переключения отдельных раскладок на отдельные комбинации клавиш? Например для трех разных языков назначить Ctrl+1, Ctrl+2 и т.д.
Sild
07.04.2016 20:47Вы можете настроить произвольную фигню через custom shortcut, назначив комбинацию клавиш на самописную баш-команду.
ageyev
08.04.2016 00:36System Settings — > Keyboard -> Shortcuts -> Custom Shortcuts
создаем новый «Custom Shortcut», даем какое-то ему имя в поле «Name» (например,
EN или RU), в поле «Command» прописываем:
gsettings set org.gnome.desktop.input-sources current 0
— эта команда будет переключать клавиатуру на раскладку которая идет первой (ну вернее нулевой), в списке All Settings -> Text Entry
и назначаем ему сочетание клавиш, например Ctrl+1
соотвественно следующие раскладки будут влючаться командами:
gsettings set org.gnome.desktop.input-sources current 1 gsettings set org.gnome.desktop.input-sources current 2 gsettings set org.gnome.desktop.input-sources current 3
Duke_kz
09.04.2016 18:34Спасибо, попробовал в вируалке, отлично работает!
ЗЫ Сорри, стрелкой вверх, увы не могу отметить такой подробный и качественный совет (
Sild
07.04.2016 16:13К слову, это всегда можно было прикрутить окольными путями:
setxkbmap «us,ru» ",winkeys" «grp:alt_shift_toggle»kvaps
07.04.2016 17:27Сейчас это принято делать так:
gsettings set org.gnome.desktop.wm.keybgdm3indings switch-input-source "['<Alt>Shift_L', '<Alt>Shift_R']" gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'us'), ('xkb', 'ru')]"
«здраствуй» gdm3Prototik
07.04.2016 18:24+1Ну незнаааааю, нормальный gdm 3 как по мне :)av0000
08.04.2016 09:32А оно научилось переключаться по клавишам-модификаторам?
У меня когда-то был любимым левый Ctrl (да, наследие самописных драйверов клавиатуры под DOS). Сейчас на LXDE/Cinnamon прикручен Caps/Shift-Caps. В своё время отказался от Гнома и «родной» Убунты в частности и из-за этого…develop7
08.04.2016 09:50+1$ gsettings get org.gnome.desktop.input-sources xkb-options ['grp:shift_caps_toggle', 'misc:typo', 'lv3:ralt_switch', 'grp_led:scroll', 'keypad:oss']
оно?
av0000
08.04.2016 09:58Почти. Надо `grp:shift_caps_switch`.
Значит, примерно тем же костылём (setxkbmap в моём случае) достижимо. В гуе, как я понимаю, по-прежнему выбор ограничен. Ну, да нам оно и не страшно.
Доедет предзаказанный планшет с убунтой — не придётся переучиваться ))
Prototik
08.04.2016 13:45«Modifiers-only switch to next source», не?
av0000
08.04.2016 15:02Возможно.
Года три уже нигде нет «честного» гнома, чтобы попробовать — или cinnamon, или mate вместо него. В Mint/Cinnamon сейчас конфигуратор раскладок как из старого второго гнома, а у остальных, кажется, из гуя не было возможности нсатроить.
Надо, чтобы по Caps был английский, а по Shift-Caps — русский.
Cheater
08.04.2016 13:08+1ИМХО не самый правильный способ — привязан к конкретной граф. среде (gdm), а если гном не единственный в системе или его нет вообще?
Правильнее класть это в конфигурацию иксов (к примеру /usr/share/X11/xorg.conf.d в моем дистрибутиве).kvaps
09.04.2016 12:18+1Я с вами полностью согласен, мой комментарий был скорее саркастичным, чем показательным.
Дело в том, что gnome3 по умолчанию игнорирует настройки xkb в xorg.
susnake
07.04.2016 16:01+2О, блин… Они это что ли до сих пор не пофиксили? В 8.04 было еще...8 лет прошло.
На вики даже 2 темы было.
http://help.ubuntu.ru/wiki/Русификация_консоли и http://help.ubuntu.ru/wiki/russian_font_in_console
Похоже нужно третью делать.
Gorthauer87
07.04.2016 16:17+2Вот интересно, есть волшебный файл /etc/vconsole.conf, который используется systemd для настройки шрифтов, почему просто им не воспользоваться?
NLO
07.04.2016 16:45НЛО прилетело и опубликовало эту надпись здесь
kotomyava
07.04.2016 17:09+2Например, чтобы видеть нормально в консоли названия файлов на русском, чтобы бывает просто необходимо.
NLO
07.04.2016 17:14НЛО прилетело и опубликовало эту надпись здесь
kotomyava
07.04.2016 17:25+3Ну суть-то описанной проблемы в том, что шрифт с юникодом не подцепляется. А без него, не только локализованные сообщения не будут работать(которые действительно не сильно-то кому нужны), но и все имена файлов содержащие символы, которых нет в стандартном шрифте, будут поломаны, что уже весьма неприятно. И кодировки тут не при чём в общем-то, как и то, что вы передаёте в LANG.
Chumicheff
08.04.2016 11:23+2Сегодня пишем на русском Хабре коммент по русски, завтра будем делать то же самое.
Зачем?
maksasila
07.04.2016 17:41-2Использование только английского интерфейса решает многие проблемы… ;)
PavelSandovin
07.04.2016 18:35+2Ага, и файлы с русскими именами не имеют прав на существование. А ведь русский — один из официальных языков ООН…
maksasila
07.04.2016 20:01-5Обхожусь без таких файлов лет 20, до сих пор жив… И да, названия файлов не на английском языке, на мой взгляд, плохая привычка. Нет русского или другого языка (я как подумаю про имя файла на иврите...) в названии файла — меньше проблем.
ageyev
08.04.2016 04:15+1Konsole на Ubuntu 14.04:
Русский и иврит в консоли, в т.ч. имя файла в котором используются одновременно три языка и с написанием слева направо (англйский и русский) и справа налево (иврит)
Без «ручных» настроек. Языки указанны в наборе клавиатур (Input soursed to use) и в Language Support, в настройках Konsole отмечено «Enable Bi-directional text rendering»maksasila
08.04.2016 10:19+1Спасибо, всё равно буду использовать только английский (латиницу) для файлов. Проблем будет меньше.
ageyev
08.04.2016 04:21+3f0rk
08.04.2016 12:05Получается, что в названии файла на иврите расширение идет в начале, а не в конце названия?
ageyev
10.04.2016 00:55В Linux, строго говоря, нет расширений.
В строке содержащей только буквы иврита вся строка будет ориентированна справа налево. Если мы напишем «расширение» на иврите, оно будет слева.
Но, если в строке будут части которые представляют собой текст на языке в котором текст пишется слева направо (английский, русский), то вся строка будет располагаться слева направо, и вставки на иврите будут располагаться в этом же порядке, хотя внутри вставок порядок расположения букв будет обратным — справа налево. Т.е. пока мы пишем на английском буквы добавляются справа, переключились на иврит, они от первой ивритской буквы добавляются слева между первой ивритской буквой и английским текстом, переключились на английский — буквы будут добавляться опять справа.
Что, имхо, логично
И так не только в именах файлов, но и вообще в тексте:
sledopit
08.04.2016 17:35Это прекрасно, но при работе в консоли жутко неудобно.
Каждый раз переключать раскладку, как только нужно прочитать ????????.txt, очень быстро надоедает.
А если его ещё и сравнивать придется, скажем, с ???????.txt, то там и вовсе запутаться недолго.maksasila
11.04.2016 21:31-2Именно, по-этому только латиница в названиях файлов.
merlin-vrn
12.04.2016 07:15+2Вам никогда файлы по электронной почте не приходят? Скачивать архивы не приходится? Вы совсем не пользуетесь софтом, который создаёт файлы в utf-8 кодировке, не задумываясь о том, какой там алфавит?
maksasila
12.04.2016 09:56Речь о том, что делаю я, а не о том, что делают другие. Я работаю в международной компании, так что всё на английском даже внутри местного офиса.
Magister7
07.04.2016 19:04В Debian testing на первой консоли тоже нету кириллицы. А вот на второй и дальше — есть.
Это если с Plymouth, без него, по крайней мере в Jessie, было все ок, ЕМНИП.
iGusev
08.04.2016 03:42-7Ubuntu. Русификация консоли в 2016 году
achekalin
08.04.2016 10:28Вот так, с помощью навязшей на зубах картинки, можно высказать свою мысль. Но зачем?
(А мятая сигарета на столе и болт размером с ширину троллейбуса странным образом не радуют, зато радуют рессоры на задней оси)
BVadim
08.04.2016 13:42+1Ставил Ubuntu Server 16.04 Beta 2. После первой загрузки была такая же проблема. Но после apt-get update && apt-get upgrade и ребута — консоль сама поправилась.
webhamster
10.04.2016 22:24-4Устал читать. Грустно становится за опенсорч, в котором баги не исправляются по пять лет, а регрессии вносятся каждые полгода пачками. В таком положении развитиею опенсорча грозит захлебнуться в собственных проблемах.
Frankenstine
12.04.2016 11:41Всегда решал «проблему» одной командой cyr в консоли, ещё с бородатых времён дебиана 5.
midaw1
12.04.2016 13:43установил пакет по ссылке https://bugs.launchpad.net/ubuntu/+source/console-setup/+bug/1565542/+attachment/4625851/+files/keyboard-configuration_1.108ubuntu9_all-fixed.deb
подтверждаю, работает на ubuntu server 16.04 LTS (beta).
напоминаю, устанавливается так:
sudo dpkg -i keyboard-configuration_*.deb
sudo apt-mark hold keyboard-configuration
ertaquo
Решал обычно как-то так:
av0000
Если склероз подводит, это пакет не рекомендовался к использованию где-то с 11.хх. Причин, за давностью лет, не упомню — что-то он там то ли ломал, то ли не срабатывал.
Потому, в своё время, прикрутил для той же цени setupcon и успокоился
EvgenT
Всегда делал так: http://help.ubuntu.ru/wiki/russian_font_in_console
На 16.04 тоже сработало.
На той же странице Ваш «костыль» во вредных советах. И я с ними согласен.
kekekeks
Автор, кажется, писал, что у него
FRAMEBUFFER=y
не заработалоkekekeks
Упс, неверно распознал ветку.