SSH で Python を実行したら UnicodeEncodeError になった
概要
ローカル環境で動作していた Python プログラムを Raspberry Pi にコピーして、 ローカル環境から SSH 経由でそのプログラムを実行したところ、 UnicodeEncodeError が発生しました。
確認環境
参考情報
- ロケール - ArchWiki
- LC_CTYPE
- 23.2. locale — 国際化サービス — Python 3.5.4 ドキュメント
- Python 3の各種エンコーディングについて - Qiita
解説
以下のプログラム (sample.py) を作成します。
print('\xa7')
IntelliJ IDEA の Terminal にて、Raspberry Pi Zero にコピーして、SSH で実行します。
intellij$ scp sample.py pi@raspberrypi.local: intellij$ ssh pi@raspberrypi.local python3 sample.py Traceback (most recent call last): File "sample.py", line 1, in <module> print('\xa7') UnicodeEncodeError: 'ascii' codec can't encode character '\xa7' in position 0: ordinal not in range(128)
ちなみに、macOS の Terminal にて、同様に実行してもエラーは発生しません。 また、Raspberry Pi に SSH でログインしてから実行してもエラーは発生しません。
Terminal によって違うのは、環境変数に違いがあると思ったので比較すると、言語設定に違いが見られます。 上から順に、IntelliJ IDEA の Terminal、 macOS の Terminal、 IntelliJ IDEA の Terminal で Raspberri Pi に SSH、 macOS の Terminal で Raspberry Pi に SSH。
intellij$ printenv LC_CTYPE=ja_JP.UTF-8 ...
mac$ printenv LANG=ja_JP.UTF-8 ...
intellij$ ssh pi@raspberrypi.local printenv LANG=en_GB.UTF-8 LC_CTYPE=ja_JP.UTF-8 ...
mac$ ssh pi@raspberrypi.local printenv LANG=en_GB.UTF-8 ...
ローカル環境のロケールを確認します。
intellij$ locale -a | grep UTF-8 ... ja_JP.UTF-8 ...
数が多いので、UTF-8
を文字に含む行だけを表示しています。
それでも、沢山のロケール名が表示されます。
Raspberry Pi Zero 環境のロケールを確認します。
intellij$ ssh pi@raspberrypi.local locale -a locale: Cannot set LC_CTYPE to default locale: No such file or directory C C.UTF-8 en_GB.utf8 POSIX
Raspberry Pi Zero 環境のロケールは全部で 4 つです。
LC_CTYPE をデフォルトロケールに使用できず、エラーが発生しています。
IntelliJ IDEA の Terminal では LC_CTYPE=ja_JP.UTF-8
ですが、ロケール ja_JP.UTF-8
は Raspberry Pi Zero 環境には存在していません。
ロケールの指定に問題があり UnicodeEncodeError が発生しています。
解決策の 1 つとしては、IntelliJ IDEA の Terminal で LC_CTYPE を unset する方法があります。
intellij$ unset LC_CTYPE
もしくは、適切な LC_CTYPE に設定すればよいでしょう。