Search code examples
linuxperlsubprocesslocale

Perl on Linux: change locale for subprocesses


What is the correct way to change the locale for a subprocess (in Linux)?

Example, when running

perl -e 'use POSIX qw(setlocale); setlocale(POSIX::LC_ALL, "C"); open F, "locale|"; while (<F>) { print if /LC_MESS/ }; close F'

I get the answer LC_MESSAGES="ca_ES.UTF-8" but I would like to obtain LC_MESSAGES="C". Whatever I've tried I can't seem to change it.

Note: I know about doing LC_ALL=C perl ..... but this is not what I want todo, I neet to change the locale inside the Perl script.


Solution

  • I'm picking up on Ted Lyngmo's comment, so credit goes to him.

    You can set the environment for your code as well as subsequent sub-processes with %ENV. As with all global variables, it makes sense to only change these locally, temporarily, for your scope and smaller scopes. That's what local does.

    I've also changed your open to use the three-arg form as that's more secure (even though you're not using a variable for the filename/command), and used a lexical filehandle. The lexical handle will go out of scope at the end of the block and close implicitly.

    use strict;
    use warnings;
    use POSIX qw(setlocale);
    
    {
        setlocale(POSIX::LC_ALL, "C");
        local $ENV{LC_ALL} = 'C';
    
        open my $fh, '-|', 'locale' or die $!;
        while (<$fh>) {
            print if /LC_MESS/
        };
    }