How to Find List of Valid Locales in My Linux Using Perl

Avoiding Setting Locale Failed Message While Calling Perl

UTF-8 is not a locale name. Set the LC_CTYPE environment variable to a locale that's recognized by your system. It should probably look like en_US.UTF-8. You can get a list of valid locales by running the command locale -a.

How to fix a locale setting warning from Perl

Your OS doesn't know about en_US.UTF-8.

You didn't mention a specific platform, but I can reproduce your problem:

% uname -a
OSF1 hunter2 V5.1 2650 alpha
% perl -e exit
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LC_ALL = (unset),
LANG = "en_US.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").

My guess is you used ssh to connect to this older host from a newer desktop machine. It's common for /etc/ssh/sshd_config to contain

AcceptEnv LANG LC_*

which allows clients to propagate the values of those environment variables into new sessions.

The warning gives you a hint about how to squelch it if you don't require the full-up locale:

% env LANG=C perl -e exit
%

or with Bash:

$ LANG=C perl -e exit
$

For a permanent fix, choose one of

  1. On the older host, set the LANG environment variable in your shell's initialization file.
  2. Modify your environment on the client side, e.g., rather than ssh hunter2, use the command LANG=C ssh hunter2.
  3. If you have administrator rights, stop ssh from sending the environment variables by commenting out the SendEnv LANG LC_* line in the local /etc/ssh/ssh_config file. (Thanks to this answer. See Bug 1285 for OpenSSH for more.)

How can I list highest version of a kernel in perl

The easiest way to do this would be to use the Sort::Versions module (which you'd need to install from CPAN).

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

use Sort::Versions;
use File::Basename;

for (sort { versioncmp($b, $a) } glob '/lib/modules/*') {
my $ver = basename $_;
if (-e "/lib/modules/$ver/vmlinuz") {
say $ver;
last;
}
}

Update: Your question includes this:

I've seen that modules for kernel version comparison or version sorting, but none are available as distro package in all release of CentOS ranging from 6 to 8 included

Of course, packages aren't the only way to install CPAN modules. You could always use cpan or cpanm. But if you really don't want to install a module that way, then you could also cut and paste the versioncmp() subroutine into your code. It's only a few dozen lines of code.

sub versioncmp ($$) {
my @A = ($_[0] =~ /([-.]|\d+|[^-.\d]+)/g);
my @B = ($_[1] =~ /([-.]|\d+|[^-.\d]+)/g);

my ($A, $B);
while (@A and @B) {
$A = shift @A;
$B = shift @B;
if ($A eq '-' and $B eq '-') {
next;
} elsif ( $A eq '-' ) {
return -1;
} elsif ( $B eq '-') {
return 1;
} elsif ($A eq '.' and $B eq '.') {
next;
} elsif ( $A eq '.' ) {
return -1;
} elsif ( $B eq '.' ) {
return 1;
} elsif ($A =~ /^\d+$/ and $B =~ /^\d+$/) {
if ($A =~ /^0/ || $B =~ /^0/) {
return $A cmp $B if $A cmp $B;
} else {
return $A <=> $B if $A <=> $B;
}
} else {
$A = uc $A;
$B = uc $B;
return $A cmp $B if $A cmp $B;
}
}
@A <=> @B;
}

gettext and locale

locale names are platform dependent.

On most unix systems you want <two letter language code>_<two letter country code>[.<optional encoding>]. You can use the command line locale -a to list valid locale names.

Proper Windows locales use the same X_X[.X] scheme except that they use full names for languages and countries, and they use code page numbers instead of encoding names: English_United States.1252. Windows also seems to have some heuristics for figuring out other strings, though it doesn't seem to go as far as working for Unix style locale names. Also Windows does not support UTF-8 as a locale encoding whether you specify it with the name 'UTF-8' or using the codepage number '65001'.

As you've found out locale names for Windows and for other platforms are different. You can't use the same string for all platforms. Instead you'll have to write code that uses the correct string for the current platform.

if Linux
return "en_US.UTF-8"
if Windows
return "English_United States.1252"

How to fix a locale setting warning from Perl

Your OS doesn't know about en_US.UTF-8.

You didn't mention a specific platform, but I can reproduce your problem:

% uname -a
OSF1 hunter2 V5.1 2650 alpha
% perl -e exit
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LC_ALL = (unset),
LANG = "en_US.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").

My guess is you used ssh to connect to this older host from a newer desktop machine. It's common for /etc/ssh/sshd_config to contain

AcceptEnv LANG LC_*

which allows clients to propagate the values of those environment variables into new sessions.

The warning gives you a hint about how to squelch it if you don't require the full-up locale:

% env LANG=C perl -e exit
%

or with Bash:

$ LANG=C perl -e exit
$

For a permanent fix, choose one of

  1. On the older host, set the LANG environment variable in your shell's initialization file.
  2. Modify your environment on the client side, e.g., rather than ssh hunter2, use the command LANG=C ssh hunter2.
  3. If you have administrator rights, stop ssh from sending the environment variables by commenting out the SendEnv LANG LC_* line in the local /etc/ssh/ssh_config file. (Thanks to this answer. See Bug 1285 for OpenSSH for more.)

Perl fails to set locale even though it is installed

Found the answer while writing the question:

The culprit is LC_CTYPE=UTF-8, which is apparently perfectly valid in macOS (and Perl will accept it there), but not on Linux. To avoid it, one can override LC_CTYPE as follows:

root@Box:~# update-locale LC_CTYPE=en_US.UTF-8

After logging out and back in again, Perl will no longer complain.

user@Box:~# perl -e 'print "Hack the Planet!\n"'
Hack the Planet!


Related Topics



Leave a reply



Submit