POSIX 쉘스크립트 및 POSIX 유틸리티에서 POSIX 로케일이 제공되지 않는다는 것을 어떻게 휴대용으로 감지할 수 있습니까?

POSIX 쉘스크립트 및 POSIX 유틸리티에서 POSIX 로케일이 제공되지 않는다는 것을 어떻게 휴대용으로 감지할 수 있습니까?

Termux는 지금까지 POSIX 로케일이 없는 유일한 POSIX 환경입니다. 결과는 다음과 같습니다.

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

Termux에서 null이 아닌 모든 바이트를 출력하는 대신 실제로 GNU awk이며 이는 로케일에 따라 다릅니다. 그러나 이 -b선택은 성공을 가져온다.

존재하다ShellShoccar-jpn/kotoriotoko 관련 문제(일본어) 일본어 및 기타 UTF-8 문자열을 적절하게 처리하는 방법에 대해 논의하고 있지만 현재 논의는 호환성을 넘어섰습니다. GAWK는 사용할 수 있지만 POSIX 로케일과 UTF-8 로케일은 사용할 수 있는지 고려하지 않습니다. 아니다. . 그렇다면 GAWK가 아닌 awk는 어떻습니까? 아마도 awk '...' | xargs -I x printf x가장 호환 가능한 아이디어 일 것입니다.

첫째, POSIX 로케일을 사용할 수 없다는 것을 어떻게 감지합니까? 지금까지 내가 생각해낸 내용은 다음과 같습니다(아직 테스트하지 않음)(또한 Termux는 locale명령이나 POSIX 로케일을 제공하지 않으며 단지 사용할 수 있다는 것도 발견했습니다 en_US.UTF-8).

# 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

하지만 모든 POSIX 환경에 적용됩니까? 그렇지 않다면 다른 옵션이 있습니까?

답변1

어떻습니까(다른 로케일도 필요함: 이 경우 UTF-8):

#!/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

위 스크립트는 C 로케일이 사용 가능한지 여부를 출력합니다.

ls -q비ASCII 문자는 다음으로 대체되어야 합니다. ing이 실제로 로케일을 변경하지 않으면 ?이 작업은 실패해야 합니다 .export

위의 주석 처리되지 않은 버전은 다음과 같은 경우 실패할 수 있습니다.야쉬사용자이고 LANGUTF-8이 아닙니다. 댓글을 달아 보세요(작동하는지 모르겠습니다).

(PS. yash 버전 2.51에서 작동, . the_script_above.sh실패)

답변2

@schily가 댓글을 달았듯이 어떨까요?

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

Termux를 사용해 보았는데 Arch GNU/Linux가 작동하는 것 같습니다.

관련 정보