내부적으로 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
정의 당시의 값에 관계없이 의 현재 값을 기준으로 계산됩니다.