~mil/sxmo-tickets#528: 
sxmo_led: Set LC_LOCALE to 'en_US' to avoid `invalid number` error

I noticed the following error in my logs: /usr/bin/sxmo_led.sh: line 69: printf: 1.00000000000000000000: invalid number

This is caused by the fact that some locales don't use the point as the decimal separator. LC_NUMERIC needs to be set to 'en_US.UTF-8'.

Status
REPORTED
Submitter
~e-v
Assigned to
No-one
Submitted
7 months ago
Updated
a month ago
Labels
No labels applied.

~mafe a month ago*

Using `de_DE.UTF-8` and I am not sure what you are writing about since I don't have this issue.
cat /etc/profile.d/locale.sh

export CHARSET=UTF-8 export LANG=de_DE.UTF-8 export LC_COLLATE=de_DE

https://git.sr.ht/~mil/sxmo-utils/tree/master/item/scripts/core/sxmo_led.sh#L67 ff. states:

max="$(cat "/sys/class/leds/$color:$type/max_brightness")"
brightness="$(echo "($percent / 100.0) * $max" | bc -l)"
printf "%0.f\n" "$brightness" > "/sys/class/leds/$color:$type/brightness"

So it looks pretty neat on the first sight.

  • L67: read whatever the system thinks the maximum brightness of the LED might be. "1" on my Pine (NoPro), "511" on my poco f1
  • L68: do some math via cmd line calculator working with computer science values as $percent / 100.0 technically creates a floating point regardless the locale
  • L69: printf "%0.f" ... says "Take whatever floating point I provide and strip that stupid fractions away".

Tried it by hand on the poco f1 and it played perfectly well.

  • Use 50% as one fictive value
  • Read the maximum via cat /sys/class/leds/white:status/max_brightness and get "511" back
  • Do the math via echo "(50 / 100.0) * 511)" | bc -l and get "260.61000000" back
  • Put it by hand via printf "%0.f\n" "260.61000" > /sys/class/leds/white:status/brightness works, file contains "260" without other stuff and LED was lid

Testing the negative way to get to some invalid number result:

  • Try the US locale by hand and echo "260.61" > /sys/class/leds/white:status/brightness and get an invalid argument error
  • Try the German locale by hand and echo "260,61" > /sys/class/leds/white:status/brightness and get an invalid argument error
  • Leave the fraction out by hand doing echo "260" > /sys/class/leds/white:status/brightness and see the status led on the poco f1 shine
  • Verify by putting stupid things like echo "test" > /sys/class/leds/white:status/brightness and get the invalid argument error.

Thesis

Whatever your system does is not related to the LC_LOCALE/LC_NUMERIC. The stored result containing the . is calculated by the bc - arbitrary-precision arithmetic language which simply does not use this environment variable as the bc man envvar section states.

Could you provide further information about your operating system and reproduce the steps of lines 67 to 69 by hand on each of your registered LEDs?

PS: It would be better to put C.UTF-8 into every pseudo-locale with programming requirements since it is slightly different and better supported than en_US.UTF-8, but I still cannot see where the locales mix things up here.

Register here or Log in to comment, or comment via email.