Не могу разобраться с локалями. Например, определить локаль.

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Ответить
Аватара пользователя
жучара
Сообщения: 937
ОС: астралинукс

Не могу разобраться с локалями. Например, определить локаль.

Сообщение жучара »

Друзья! Согласно man locale
If locale is NULL, the current locale is only queried, not modified.
и вот этому
https://www.gnu.org/software/libc/manual/html_node/Setting-the-Locale.html
определяю текущую локаль:

Код: Выделить всё

/*foo.cpp*/
#include <stddef.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main ()
{
 	printf ("%s\n", setlocale (LC_TIME, NULL));
}

Shell

$ gcc foo.cpp
$ ./a.out
C
$
То есть она у меня С. Ну хорошо, а теперь в этой же консоли сразу же:

Shell

$ locale
LANG=ru_RU.UTF-8
LANGUAGE=
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
$
А тут вообще не С, а LC_TIME="ru_RU.UTF-8". Так какая же у меня на самом деле локаль? Спасибо, кто откликнется. Debian 10.
Я просто читаю маны.
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5282
ОС: Gentoo

Re: Не могу разобраться с локалями. Например, определить локаль.

Сообщение /dev/random »

Вы вообще ман к функции setlocale() читали? Там всё подробно расписано.

setlocale(категория, NULL) не читает значение из окружения, а возвращает значение, установленное в данный момент для этой программы. Вы можете, например, сменить локаль через setlocale(категория, "ru_RU.UTF-8"), и после этого будет возвращаться это значение. Чтобы прочитать локаль из окружения или других системных параметров (в зависимости от операционки) и установить её в качестве текущей для программы, вызовите setlocale(категория, "") (т.е. с пустой строкой). В момент запуска любой программы, для неё устанавливается локаль "C". Если программа знает, как работать с другими локалями, и программист уверен, что их установка не вызовет багов, то нужно установить другое значение, обычно через пустую строку.
Спасибо сказали:
Аватара пользователя
Ater
Сообщения: 170
Статус: Дважды Будда Советского Союза
ОС: Gentoo

Re: Не могу разобраться с локалями. Например, определить локаль.

Сообщение Ater »

Ну вот смотрите. При запуске программы для нее по умолчанию устанавливается локаль "С", независимо от окружения. Функция setlocale со вторым параметром NULL возвращает это значение без модификации (man locale, как Вы и указали). Вот прога Вам его и вернула.
То же самое, но другими словами.
Вас смущает то, что в консоли выхлоп другой? Так ведь там шелл, грубо говоря, прочитал из конфигов это значение и установил для себя, но не для дочерних процессов по умолчанию.
У меня, кстати, результат точно такой же.
Азъ есмь БҌшеный Їзюмъ
Спасибо сказали:
Аватара пользователя
жучара
Сообщения: 937
ОС: астралинукс

Re: Не могу разобраться с локалями. Например, определить локаль.

Сообщение жучара »

Ater писал:
15.02.2023 17:28
Ну вот смотрите. При запуске программы для нее по умолчанию устанавливается локаль "С", независимо от окружения. Функция setlocale со вторым параметром NULL возвращает это значение без модификации (man locale, как Вы и указали). Вот прога Вам его и вернула.
То же самое, но другими словами.
Вас смущает то, что в консоли выхлоп другой? Так ведь там шелл, грубо говоря, прочитал из конфигов это значение и установил для себя, но не для дочерних процессов по умолчанию.
У меня, кстати, результат точно такой же.
да, мне нужно в шелле. А как мне там установить, чтобы было LC_TIME="C"?
Реально всё запутано. Допустим, так я установил:

Shell

$ sudo update-locale LC_TIME=C
$ cat /etc/default/locale
LANG=ru_RU.UTF-8
LC_TIME=C
$
Но это, наверное, нещитово, я не знаю, ибо тут всё по-прежнему

Shell

$ locale
LANG=ru_RU.UTF-8
LANGUAGE=
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
$
Я просто читаю маны.
Спасибо сказали:
Аватара пользователя
Ater
Сообщения: 170
Статус: Дважды Будда Советского Союза
ОС: Gentoo

Re: Не могу разобраться с локалями. Например, определить локаль.

Сообщение Ater »

Извините, не совсем понимаю.
1. Вы хотите, чтобы в консоли было LC_TIME=C? Зачем, если не секрет?
2. После правки конфига шелл перезапускали? source /etc/profile пробовали?
Азъ есмь БҌшеный Їзюмъ
Спасибо сказали:
Аватара пользователя
жучара
Сообщения: 937
ОС: астралинукс

Re: Не могу разобраться с локалями. Например, определить локаль.

Сообщение жучара »

Ater писал:
15.02.2023 18:02
Извините, не совсем понимаю.
1. Вы хотите, чтобы в консоли было LC_TIME=C? Зачем, если не секрет?
2. После правки конфига шелл перезапускали? source /etc/profile пробовали?
ответ на второй вопрос: пробовал и перезапускал. Оно непоколебимо что ли?

Shell

$ cat /etc/default/locale
LANG=ru_RU.UTF-8
LC_TIME=C
$
$ source /etc/profile
$
$ locale
LANG=ru_RU.UTF-8
LANGUAGE=
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
$
Я просто читаю маны.
Спасибо сказали:
Аватара пользователя
Ater
Сообщения: 170
Статус: Дважды Будда Советского Союза
ОС: Gentoo

Re: Не могу разобраться с локалями. Например, определить локаль.

Сообщение Ater »

жучара
Сегодня уже вряд ли, но завтра доберусь до машины с *бунту и посмотрю. Если будет еще актуально, отпишусь. Уже самому интересно стало.
Азъ есмь БҌшеный Їзюмъ
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2604
ОС: Gentoo

Re: Не могу разобраться с локалями. Например, определить локаль.

Сообщение ormorph »

Хм, т. е. назначить переменную родителю из потомка. Не думаю что это возможно, кроме как только из самого родителя.
Спасибо сказали:
Аватара пользователя
жучара
Сообщения: 937
ОС: астралинукс

Re: Не могу разобраться с локалями. Например, определить локаль.

Сообщение жучара »

Чтобы вот тут

Shell

$ locale
LANG=ru_RU.UTF-8
LANGUAGE=
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
$
локаль была какой нужно, достаточно вручную изменить файл /etc/default/locale, например, вот так:

Shell

$ cat /etc/default/locale
LANG=en_US.UTF-8
$
После изменений будем наблюдать такую картину:

Shell

$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
$
Ну то есть один пункт как бы управляет другими пунктами.
LANG управляет всеми, кроме LANGUAGE и LC_ALL. LANGUAGE и LC_ALL непонятно чем управляют, их я не трогал. Остальные пункты не управляют ничем кроме себя самих. Изменения, внесённые в файл /etc/default/locale проявляются при команде locale после входа-выхода из сессии, ну то есть команды "sudo service lightdm restart". Ну, естессно, после перезагрузки они тоже появляются.

Это я эксперементировал с установленными локалями, которые вот эти:

Shell

$ cat /etc/locale.gen | grep -v \#

en_US.UTF-8 UTF-8
ru_RU.UTF-8 UTF-8
$
Предполагаем, что на эти локали, всё вышесказанное тоже распространяется:

Shell

$ locale -a
C
C.UTF-8
en_US.utf8
POSIX
ru_RU.utf8
$
А за все остальные локали, которые просто есть в файле /etc/locale.gen, но они закомменчены, я не знаю. И что всё это значит, я тоже не знаю.
Я просто читаю маны.
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2604
ОС: Gentoo

Re: Не могу разобраться с локалями. Например, определить локаль.

Сообщение ormorph »

жучара писал(а):
16.02.2023 20:06
LANGUAGE и LC_ALL непонятно чем управляют
Ну за что управляет LANGUAGE я не знаю, у меня в выводе этот параметр отсутствует, а вот LC_ALL фиксирует все параметры кроме LANG согласно заданного:

Код: Выделить всё

#include <stdlib.h>

int main ()
{
	setenv("LANG", "ru_RU.UTF-8", 1);
	setenv("LC_ALL", "ru_RU.UTF-8", 1);
	//setenv("LC_ALL", "C.utf8", 1);
	setenv("LC_TIME", "C.utf8", 1);
	//unsetenv("LC_ALL");
	system("locale");
	system("locale -k LC_TIME");
}
Попробуйте раскомментируйте строчку setenv("LC_ALL", "C.utf8", 1), а затем сравните вывод а потом тоже самое проделайте с unsetenv("LC_ALL") и сравните вывод. При заданной переменной LC_ALL, другие переменные из locale будут привязаны к этому параметру.
Спасибо сказали:
Аватара пользователя
жучара
Сообщения: 937
ОС: астралинукс

Re: Не могу разобраться с локалями. Например, определить локаль.

Сообщение жучара »

Можно так ещё:

Shell

$ LC_TIME=C
$ locale
LANG=ru_RU.UTF-8
LANGUAGE=
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME=C
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
$
$ LC_TIME=en_US.UTF-8
$ locale
LANG=ru_RU.UTF-8
LANGUAGE=
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME=en_US.UTF-8
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
$
$ LC_TIME=ru_RU.UTF-8
$ locale
LANG=ru_RU.UTF-8
LANGUAGE=
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME=ru_RU.UTF-8
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=
$
странно всё это.
Я просто читаю маны.
Спасибо сказали:
Аватара пользователя
ormorph
Сообщения: 2604
ОС: Gentoo

Re: Не могу разобраться с локалями. Например, определить локаль.

Сообщение ormorph »

жучара писал(а):
17.02.2023 10:16
странно всё это.
Ни чего странного, так оно и работает, это тоже самое что я привел на C. Но стоит объявить переменную LC_ALL, как эти переменные по отдельности уже не будут действовать, всё будет привязано к LC_ALL, снова начнёт работать по отдельности как только выполнишь unset LC_ALL. Экспорт переменных нужен для новых процессов bash(sh).
Спасибо сказали:
Аватара пользователя
olecya
Сообщения: 900
ОС: debian, fedora (i3-wm)

Re: Не могу разобраться с локалями. Например, определить локаль.

Сообщение olecya »

ormorph
Тому пример в подтверждение:

Shell

LC_TIME=fr_FR.UTF-8 locale mon
janvier;février;mars;avril;mai;juin;juillet;août;septembre;octobre;novembre;décembre

LC_ALL=C LC_TIME=fr_FR.UTF-8 locale mon
January;February;March;April;May;June;July;August;September;October;November;December

Shell

LC_NUMERIC=fr_FR.UTF-8 seq -f'%f' 2
1,000000
2,000000

LC_ALL=C LC_NUMERIC=fr_FR.UTF-8 seq -f'%f' 2
1.000000
2.000000
Спасибо сказали:
Ответить