터미널과 쉘 스크립트를 사용한 다양한 인코딩/유니코드 설명

터미널과 쉘 스크립트를 사용한 다양한 인코딩/유니코드 설명

저는 키 매핑 스크립트(한 언어 키보드 레이아웃에서 다른 언어 키보드 레이아웃으로 키 매핑)를 작성 중입니다. 모든 것이 작동하도록 하기 위해 많은 노력을 기울인 끝에 나는 모든 프로그램(Perl, Python)에서 다양한 문자가 다르게 처리된다는 것을 발견했습니다. 그런 다음 터미널(kitty, gnome-terminal - 중요하지 않음)에서 간단한 테스트 스크립트(이제 단순화됨)를 실행합니다.

python -c 'import sys;print(len(sys.argv[1]))' テスト

예상되는 결과를 얻었습니다.

3

하지만 sh/bash(unix&utf-8) 파일에서 실행하면:

#!/usr/bin/env bash
# or
#!/bin/sh
python -c 'import sys;print(len(sys.argv[1]))' テスト

나는 얻다( ./test.sh):

9

이것이 UTF-8 인코딩/디코딩/업그레이드/다운그레이드가 Perl에서 작동하지 않는 이유입니다(터미널에서 수동으로 명령을 실행하면 이 모든 추가 인코딩 기능 없이도 작동할 수 있습니다).

이제 질문이 있습니다. 정확히 동일한 명령이 실행 환경(터미널 에뮬레이터와 셸 스크립트)에 따라 다른 결과를 제공하는 이유는 무엇입니까? 이 문제를 어떻게 해결할 수 있나요?

고쳐 쓰다:

내 것을 잊어버렸어요:

alias python='python3'

따라서 Python의 경우 python3명시적으로 실행하면 두 경우 모두 모든 것이 동일해집니다. 그러나 반면에 Perl의 경우:

echo 'print length $ARGV[0];' | perl -l -- - テスト

그것은 동일하게 작동하지만 두 경우 모두 인쇄됩니다 9. Perl의 다른 버전은 없습니다. 내 버전은 5.30.0입니다(두 경우 모두 인쇄된 버전은 정확히 동일합니다). Python3처럼 작동하도록 Perl 자체에 일부 코드를 추가해야 합니까(1 유니코드 문자의 길이는 1-3바이트가 아닌 1바이트입니다)?

답변1

이것은 쉘에 관한 것이 아니라 pythonpython3과 python2를 사용하여 동일한 명령을 명시적으로 실행하여 이를 재현할 수 있습니다.

$ python3 -c 'import sys;print(len(sys.argv[1]))' テスト
3
$ python2 -c 'import sys;print(len(sys.argv[1]))' テスト
9

특정 실행 파일의 전체 경로를 사용하지 않기 때문에 터미널과 스크립트 모두 .txt에 나열된 디렉터리에서 찾은 python첫 번째 경로를 사용합니다. 귀하의 경우, 비대화형 셸(스크립트를 실행하는 것)에 있는 것이 대화형 셸(터미널에서)에 있는 것과 다르며, 전자에서는 분명히 Python2 실행 파일을 가리킵니다.pythonPATHPATHPATHpython

왜 이것이 있는지 모르겠습니다. 귀하의 설정과 사용 중인 OS에 대해 더 자세히 알아야 합니다. 그러나 이를 제공하는 시스템을 사용한다고 가정할 때 간단한 해결책은 다음 python3스크립트를 호출하는 것입니다 python.

python3 -c 'import sys;print(len(sys.argv[1]))' テスト

또는 전체 경로를 사용하십시오( 참조 type -a python).

/usr/bin/python -c 'import sys;print(len(sys.argv[1]))' テスト

이렇게 하면 결과가 항상 일관되게 유지됩니다.

관련 정보