스크립트 내에서 쉘 스크립트 문자 인코딩을 적용하는 방법

스크립트 내에서 쉘 스크립트 문자 인코딩을 적용하는 방법

내부적으로 UTF8로 인코딩된 문자를 포함하는 일부 셸 스크립트가 있는데 컴퓨터 로케일에 관계없이 올바르게 디코딩되는지 확인하고 싶습니다.

쉘(bash 또는 sh)이 올바른 스크립트 인코딩을 감지하도록 강제할 수 있습니까? (Python 또는 Ruby 인코딩 쿠키와 유사)

해결책은 다음과 같은 맞춤형 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정의 당시의 값에 관계없이 의 현재 값을 기준으로 계산됩니다.

관련 정보