3

I'd like to create a new locale on FreeBSD. I thought that I can just copy one of the existing ones in /usr/share/locale but apparently it is not so simple.

Firstly, I just create a copy of the en_US.UTF-8 locale.

$ sudo cp -R /usr/share/locale/en_US.UTF-8 /usr/share/locale/en_DK.UTF-8

I am testing my setup with mosh, so with the standard en_US.UTF-8 everything is fine:

$ LC_ALL=en_US.UTF-8 PATH_LOCALE=/usr/share/locale mosh xyz.example.org

However, if I try to use the newly created en_DK.UTF-8 locale I get the following errors:

$ LC_ALL=en_DK.UTF-8 PATH_LOCALE=/usr/share/locale mosh xyz.example.org
The locale requested by LC_ALL=en_DK.UTF-8 isn't available here.
Running `locale-gen en_DK.UTF-8' may be necessary.

mosh-server needs a UTF-8 native locale to run.

Unfortunately, the local environment ([no charset variables]) specifies
the character set "US-ASCII",

The client-supplied environment (LC_ALL=en_DK.UTF-8) specifies
the character set "US-ASCII".

sh: warning: setlocale: LC_ALL: cannot change locale (en_DK.UTF-8)
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=en_DK.UTF-8
LC_CTYPE="en_DK.UTF-8"
LC_NUMERIC="en_DK.UTF-8"
LC_TIME="en_DK.UTF-8"
LC_COLLATE="en_DK.UTF-8"
LC_MONETARY="en_DK.UTF-8"
LC_MESSAGES="en_DK.UTF-8"
LC_PAPER="en_DK.UTF-8"
LC_NAME="en_DK.UTF-8"
LC_ADDRESS="en_DK.UTF-8"
LC_TELEPHONE="en_DK.UTF-8"
LC_MEASUREMENT="en_DK.UTF-8"
LC_IDENTIFICATION="en_DK.UTF-8"
LC_ALL=en_DK.UTF-8
Connection to xyz.example.org closed.
/usr/local/bin/mosh: Did not find mosh server startup message. (Have you installed mosh on your server?)
5

It seems like you are trying a Linuxism on FreeBSD. On FreeBSD you should use login classes

There is a great general description of locales in What should I set my locale to and what are the implications of doing so?.

The part in that answer you can ignore is "Installing locales". FreeBSD comes with all common locales installed. You can verify this with

locale -a

But then you probably claim that you try to modify the locale and set that. And that is what I call the Linuxism. People add the locale to linux without understanding what actually happened and then set LC_ALL. The locale defines a set of LC_* variables. LC_ALL is then used to override those!

On FreeBSD the preferred way of changing the locale settings for a user (or system) is to use 22.2.1.1. Login Classes Method. You can change the system wide defaults here as well.

LC_ALL should only be set if you want to (forcefully) overrule any and all of the other LC_* settings. You might think you are setting a "locale" with LC_ALL but in effect you are just setting LANG to LANG=en_DK.UTF-8. That is not a valid language and you should leave that to the Unicode CLDR Project. For more info on that have a look at What does “LC_ALL=C” do?

My quess is then that you do not want to invent your own new language. But from the combinations you choose my guess is that you would like the system to behave as a danish (DK) system but talk english to you. For that you can mix and match your LC_* variables to your heats content.

Example:

LANG=en_US.UTF-8
LC_CTYPE="da_DK.UTF-8"
LC_COLLATE="da_DK.UTF-8"
LC_TIME="da_DK.UTF-8"
LC_NUMERIC="da_DK.UTF-8"
LC_MONETARY="da_DK.UTF-8"
LC_MESSAGES="en_US.UTF-8"

If you do not want to set you login class (for some reason) then you should still stick to the CLDR defined variables. That will give you the most portable results:

$ LC_ALL=C LANG=en_US.UTF-8 LC_CTYPE=da_DK.UTF-8 LC_COLLATE=da_DK.UTF-8 LC_TIME=da_DK.UTF-8 LC_NUMERIC=da_DK.UTF-8 LC_MONETARY=da_DK.UTF-8 LC_MESSAGES=en_US.UTF-8 mosh xyz.example.org
/usr/local/bin/mosh: could not get canonical name for xyz.example.org: hostname nor servname provided, or not known
ssh_exchange_identification: Connection closed by remote host
/usr/local/bin/mosh: Did not find remote IP address (is SSH ProxyCommand disabled?).
$

If it is a locale setup you want to use commonly then you can set it up using a login class. Either see the FreeBSD Handbook or my answer to SSH to FreeBSD in UTF-8

I think your answer lies somewhere above. But if we take you question verbatim then FreeBSD current will add a UTF-8 C locale in 13.0 (see commit r340144). If you really truly want to see how to add a new locale then have a look at introduce C.UTF-8 locale

UPDATE

The directory /usr/share/locale/* is just a directory. If you make a verbatim copy as in the Q - things will work on FreeBSD 11.2. I still recommend using a verbose LC_ALL or login classes. For now I think the problem has been "fat fingers".

The directory contains symlinks and definition files. The files can be created by localdef which replaced mklocale in 2015.

If you do not want to change the actual collation order then you can link to a language which have the "proper" collation order - or simply copy the file. PATH_LOCALE=/usr/share/locale is implicit as it is the default.

I made a verbatim copy on my system to test and en_DK.UTF-8. They show up with locale -a immediately. Both worked as expected:

$ locale -a | grep -e en_DK -e test
en_DK.UTF-8
test
$ LC_ALL=test mosh xyz.example.org
/usr/local/bin/mosh: could not get canonical name for xyz.example.org: hostname nor servname provided, or not known
ssh_exchange_identification: Connection closed by remote host
/usr/local/bin/mosh: Did not find remote IP address (is SSH ProxyCommand disabled?).
$ LC_ALL=test /bin/sh
$ locale
LANG=
LC_CTYPE="test"
LC_COLLATE="test"
LC_TIME="test"
LC_NUMERIC="test"
LC_MONETARY="test"
LC_MESSAGES="test"
LC_ALL=test
$ exit
$ LC_ALL=en_DK.UTF-8 mosh xyz.example.org
/usr/local/bin/mosh: could not get canonical name for xyz.example.org: hostname nor servname provided, or not known
ssh_exchange_identification: Connection closed by remote host
/usr/local/bin/mosh: Did not find remote IP address (is SSH ProxyCommand disabled?).
$ LC_ALL=dummy mosh xyz.example.org
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LC_ALL = "dummy",
        LANG = (unset)
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LC_ALL = "dummy",
        LANG = (unset)
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
/usr/local/bin/mosh: could not get canonical name for xyz.example.org: hostname nor servname provided, or not known
ssh_exchange_identification: Connection closed by remote host
/usr/local/bin/mosh: Did not find remote IP address (is SSH ProxyCommand disabled?).
$ uname -a
FreeBSD test 11.2-RELEASE FreeBSD 11.2-RELEASE #0 r335510: Fri Jun 22 04:32:14 UTC 2018     root@releng2.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64
  • Thank you for the answer. This is a good summary of a research I did on my own. I do want to add a new locale, however. en_DK is a popular name for locales featuring English language with some other settings like 24-hour clock, yyyy-mm-dd date format and EUR as the currency (see the post about en_DK.UTF-8 here). I guess if I really want to add it, I have to understand how to properly introduce locale in FreeBSD. – Mateusz Piotrowski Nov 4 '19 at 13:01
  • I think it is a question of either human error on your side. Or I simply do not understand what you are trying to do. Beer, cake or rephrasing is needed :-) – Claus Andersen Nov 4 '19 at 13:09
  • I am trying to improve the support for the misc/locale-en_DK port. The goals of this locale cannot be achieved, as far as I know, by setting various LC_* variables to one of the existing locales. The current problem is, that in order to add a new locale it is not sufficient to just add some files to /usr/share/locale/en_DK.UTF-8. In the question I posted I wanted to know what the proper way of adding new locales is on FreeBSD. – Mateusz Piotrowski Nov 4 '19 at 13:15
  • After the recent update to the answer, I guess it can be a fat-fingers problem :) . I'll post an update soon. – Mateusz Piotrowski Nov 4 '19 at 13:16
  • Either what is done in the pkg can be done with a login class. Or they are having a weird collation order (or some such) which conflicts with CLDR. That would be stupid. But if that is what is wanted then mklocale is needed. That could be interesting to flesh out in a different question. Being danish I can say that the package creator is trying to impose his standards on the rest of the world. If he genuinely want to mix danish and english conventions then login class is the way to go! – Claus Andersen Nov 4 '19 at 13:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.