スクリプト内でシェルスクリプト文字エンコーディングを適用する方法

スクリプト内でシェルスクリプト文字エンコーディングを適用する方法

内部的にUTF8でエンコードされた文字を含むいくつかのシェルスクリプトがあり、コンピュータのロケールに関係なく正しくデコードされていることを確認したいと思います。

シェル(bashまたはsh)が正しいスクリプトエンコーディングを検出するように強制できますか? (PythonまたはRubyエンコードCookieに似ています)

解決策は、次のカスタマイズされたshebangです。

#!/bin/bash --utf8

このソリューションはより良い移植性を目指す必要があるため、bashに固執する必要はありません。

編集:たぶん再帰スクリプト呼び出しを使用して可能な解決策を見つけたかもしれません。

# check if current locale is UTF8-based (otherwise this script may not work correctly)
locale | grep -q 'UTF-8'
if [ $? -ne 0 ]; then
    export LC_ALL=en_GB.UTF-8
    # recursive call this script with the modified environment
    $0 "$@"
    exit $?
fi

ベストアンサー1

Bash は文字列をバイト文字列として保存し、LC_CTYPE現在の設定に従って操作を実行します。したがって、bashを再起動する必要はありません。LC_CTYPEまたは、LC_ALL変数を目的のロケールに設定するだけです。変数または関数に文字列を格納する場合は、変数を拡張したり、関数から関連コマンドを実行したりするときにエンコーディングを覚えておくことが重要です。以下はこれを示すスクリプトです。

#!/bin/bash
LC_CTYPE=en_US.utf8
v_utf8='é'
n_utf8=${#v_utf8}
f_utf8 () { tmp='é'; echo ${#tmp}; }
echo "UTF-8 in UTF-8: $n_utf8 $(f_utf8)"
LC_CTYPE=en_US
v_latin1='é'
n_latin1=${#v_latin1}
f_latin1 () { tmp='é'; echo ${#tmp}; }
echo "Latin 1 in Latin 1: $n_latin1 $(f_latin1)"
echo "UTF-8 in Latin 1: ${#v_utf8} $(f_utf8)"
LC_CTYPE=en_US.utf8
echo "Latin 1 in UTF-8: ${#v_latin1} $(f_latin1)"

出力:

UTF-8 in UTF-8: 1 1
Latin 1 in Latin 1: 2 2
UTF-8 in Latin 1: 2 2
Latin 1 in UTF-8: 1 1

ご覧のとおり、文字列の長さは、定義LC_CTYPE時の値に関係なく、現在の値に基づいて計算されます。

おすすめ記事