Posix

如何檢測 POSIX shellscript 和 POSIX 實用程序上沒有提供 POSIX 語言環境,可移植?

  • January 19, 2022

到目前為止,我發現 Termux 是唯一沒有 POSIX 語言環境的 POSIX 環境;結果是以下命令,例如:

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

不是輸出每個非空字節;Termux 上的 awk 實際上是 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 環境?如果沒有,還有其他選擇嗎?

這個怎麼樣(也需要其他語言環境: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 字元,?如果exporting 實際上沒有更改語言環境,這應該會失敗。

如果您是yash使用者並且LANG不是 UTF-8,則上面未註釋的版本可能會失敗:請嘗試註釋一個(我不知道它是否有效)。

(PS。在 yash 的 2.51 版上工作;. the_script_above.sh失敗)

引用自:https://unix.stackexchange.com/questions/631870