0

So far I have found that Termux is the only POSIX environment without POSIX locale; as a result the following command, for example:

awk 'BEGIN{for(i=1;i<256;i++)printf"%c",i;}'

outputs not every non-null byte; the awk on Termux is actually GNU awk and it seems to depend on locale. The -b option, however, makes it succeed.

On issue for ShellShoccar-jpn/kotoriotoko (Japanese) we are discussing how to handle Japanese and other UTF-8 strings proparely, but at this point the discussion is going somewhere out of compatibility; the latest idea doesn't think of what if GAWK is available but POSIX locale and UTF-8 locales are not available. Also what about non-GAWK awk? Maybe awk '...' | xargs -I x printf x is the most compatible idea.

First, how to detect that POSIX locale is not available? So far I have thought of these (never tested yet) (also I have found out that Termux does never serve locale command nor POSIX locale; only en_US.UTF-8 is available):

# 1
POSIX_LOCALE_AVAILABLE=no
type locale >/dev/null 2>&1 && {
   locale -a |
   grep -qE '^(C|POSIX)$' &&
   POSIX_LOCALE_AVAILABLE=yes
}

# 2
export LC_ALL=C
POSIX_LOCALE_AVAILABLE=no
case "$LC_ALL" in ('C')
   POSIX_LOCALE_AVAILABLE=yes
;;esac

# 3
POSIX_LOCALE_AVAILABLE=no
case "$(
   LC_ALL=C awk 'BEGIN{for(i=1;i<256;i++)printf"%c",i;}' |
   od -A n -t x1 -v |
   tr ABCDEF abcdef |
   tr -Cd abcdef1234567890
)" in ("$(
   awk 'BEGIN{for(i=1;i<256;i++)printf"%02x",i;}'
)")
   POSIX_LOCALE_AVAILABLE=yes
;;esac

But do they work on every POSIX environment? If not, any alternatives?

7
  • 2
    #2 just confirms that you’ve set LC_ALL=C, the shell doesn’t restrict the values that can be specified. Jan 31, 2021 at 8:01
  • Thanks; that did never solve anything, as you said so. I confirmed it on my Termux.
    – user451199
    Jan 31, 2021 at 8:05
  • 1
    The best that you can do is prove that it is available. You can't prove a negative: You can't prove that all swans are white. I have seen many white swans, and no non-white swans, but this proves nothing. Eventually the hypothesis (not proof) that all swans are white was disproved, when black swans were found. Jan 31, 2021 at 8:35
  • So does that mean that we have to believe that #1 and #3 are the ways to detect that POSIX locale IS available? Also we would have to list all POSIX-compliant and POSIX-like environments and validate for all of them to confirm my hypithesis works everywhere.
    – user451199
    Jan 31, 2021 at 11:31
  • 1
    If you like to make your script POSIX compliant, you need to set PATH to the result from getconf PATH. I cannot see a dependence to GAWK since you do not use the GNU option -b in the scripts. It would help, if you did explain your exact problems.
    – schily
    Feb 2, 2021 at 11:16

2 Answers 2

0

How about this (requires other locales too: UTF-8, in this case):

#!/bin/sh
export LC_ALL=C
# alternatively:
# a="$(printf \\343\\201\\202)" # actually あ
# case "$(mkdir "$a" && ls -dq "$a" && rmdir "$a")" in ("$a")
# end alternative
case "$(mkdir あ && ls -dq あ && rmdir あ)" in (あ)
  echo NO
;;(*'?'*)
  echo YES
;;(*)
  echo WTF
;;esac

The script above outputs whether C locale is available or not.

ls -q should replace non-ASCII characters with ?: this should fail if exporting does not actually change the locale.

The uncommented version above may fail if you're a yash user and LANG is not UTF-8: try commented one, please (I have no ideas if it works).

(PS. Worked on version 2.51 of yash; . the_script_above.sh to fail)

0

How about this, as @schily commented:

if command -p getconf PATH | grep .; then
   : 'LC_ALL=C is available'
else
   : 'LC_ALL=C is not available'
fi

I tried on Termux and Arch GNU/Linux; seemed working.

You must log in to answer this question.