8

I made an script that do some math, using bc and printf.

It worked well under cygwin which locale is en_US.UTF-8, but when I run it under linux, which locale is en_ES.UTF-8, it fails because it uses , as decimal separator. For example next expression fails:

avg=$(printf %.2f $(echo "scale=4; $val1/$val2" | bc -l )) 

I found a solution. Precede the script by LC_ALL=C.UTF8:

LC_ALL=C.UTF8 ./script.sh [OPTIONS] 

However, I think it would be better not to do that.
So, my question: Is there a way to change locale only inside the script, to avoid such kind of problems, regardless of locale set in user profile?

2
  • see unix.stackexchange.com/a/87763/117549
    – Jeff Schaller
    Feb 3, 2016 at 12:00
  • @JeffSchaller, Yes, I already read it, but if I didn't misunderstand it overrides locale the way I did: preceding command by LC_XXX=YYY. The only case that it's used in a script is when using ksh93 shell, but it overrides using typeset LC_ALL=C instead of export LC_ALL=C. I'm using bash, can I do the same? If so, is there a difference in bash between typeset LC_ALL=C and export LC_ALL=C?
    – Albert
    Feb 3, 2016 at 12:32

1 Answer 1

13

Inside the script, simply export LC_ALL=C.UTF-8¹ at the beginning (just after the shebang line, if any).

Then, all commands executed by the script will inherit LC_ALL.

If you need part of your script to be immune to locale changes, but part to respect the locale (for instance, if you are to calculate and then print some values), you might need to unset LC_ALL after the calculation and before the printing. Alternatively, you might choose to prefix just some commands in your script with a per-command setting.


  1. Some platforms spell the UTF-8 version of C locale differently (different case and/or lack of hyphen in UTF-8). A more platform-independent version is:

     export LC_ALL=$(locale -a|grep -ix 'c.utf-\?8' || echo C)
    
7
  • It worked perfectly, but locale is different under cygwin and linux. In cygwin is c.utf8, whereas in linux is C.UTF-8 and I cannot find how to use same script that works in the same way in any bash shell (modern). Thanks.
    – Albert
    Feb 4, 2016 at 17:18
  • 1
    Possibly helpful: Check if a specific locale is enabled in bash Feb 16, 2018 at 12:57
  • Note: export LC_ALL=... does not change LANG and LANGUAGE (test with locale command)
    – honzajde
    Nov 29, 2020 at 19:53
  • 1
    In my Fedora 32 it's C.utf8, so giving those variations among linux flavors, the best is to just prefix the C locale before an specific arithmetic command, like this: result=$(LC_ALL=C your_arithmetic_command)
    – Nelson
    Jan 3, 2021 at 23:47
  • Yes @Nelson, good idea. Since the C locale should be using the ASCII subset of UTF-8, that should just work. Jan 4, 2021 at 14:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .