Git BashとCmderで快適bash生活始めようとしたらPythonが文字化けした。
$ python -c "print('日本語')"
譌・譛ャ隱・
結論
- 
chcp.com 65001でコードページをUTF-8にする
- 
export PAGER=lessでページャにlessコマンド(Git for Windowsに付属)を指定する
つまり以下の二行を.bashrcに追加だ。
chcp.com 65001
export PAGER=less
結論としては以上だが、そこに至った背景も残しておく。
問題1: 文字化け
$ python -c "print('日本語')"
譌・譛ャ隱・
調査
思いつく限りの文字エンコーディング確認コマンドを打った。
$ echo $LANG
ja_JP.UTF-8
$ echo $PYTHONIOENCODING
utf-8
$ python -c "import sys; print(sys.stdout.encoding)"
utf-8
$ python -c "import sys; print(sys.getdefaultencoding())"
utf-8
$ python -c "import locale; print(locale.getpreferredencoding(False))"
cp932
ほとんどUTF-8と返ってくる。
locale.getpreferredencoding()だけはcp932っぽい応答をしたが、ドキュメントによるとこれは:
テキストデータをエンコードする方法を、ユーザの設定に基づいて返します。ユーザの設定は異なるシステム間では異なった方法で表現され、システムによってはプログラミング的に得ることができないこともあるので、この関数が返すのはただの推測です。
とのことでいまいちあやしい。
そうこうしている中でsys.stdoutのドキュメントに以下の記述を見つけた:
文字エンコーディングはプラットフォーム依存です。Windows では、ストリームが対話型 (isatty() メソッドが True を返す場合) であれば、コンソールのコードページが、それ以外では ANSI コードページが使用されます。その他のプラットフォームでは、ロケールのエンコーディングが使用されます (locale.getpreferredencoding() を参照)。
コードページ…!
対処: コードページ変更
コードページを知らなかったのでググった。chcpコマンドで設定するものらしい。
Git Bash上からでも/C/windows/system32にパスが通っていれば、拡張子付きの名前chcp.comで呼び出せる。
$ chcp.com          # コードページ確認
現在のコード ページ: 932
$ chcp.com 65001    # コードページ設定(UTF-8)
$ python -c "print('日本語')"
日本語
晴れて文字化けを退治した。
問題2: ヘルプ表示エラー
Pythonでヘルプが見れなくなってしまった。Not enough memory.と表示される。
>>> import sys
>>> help(sys.argv)
Not enough memory.
調査
chcp 65001の環境下ではWindowsのmore.comがうまく動作しないらしい。
表示したい内容が数ページに跨る時に、-- More (40%) --とか表示してキー入力を促すもの。こういう機能はページャと呼ばれる。
Linuxでは通常lessコマンドがその役割をする。
使えなくなったmore.comの代わりにless.exeを使いたい!
対処: ページャ変更
Pythonは環境変数PAGERに指定しておけばそれを使ってくれるっぽい。
ドキュメントでは特にページャへの言及は見つけきれなかった。自明の事なのか、Python以外の機能だからなのか。
$ export PAGER=less
$ python
>>> import sys
>>> help(sys.argv)  # ここから下はlessの画面で表示されるため、一旦Pythonインタプリタは隠れる
Help on list object:
class list(object)
 |  list() -> new empty list
 |  list(iterable) -> new list initialized from iterable's items
 |
 |  Methods defined here:
 |
...
めでたくhelpが復活した。
今回はPythonのヘルプ表示で気がついたが、他にもmore.comを使っているものは同じ問題にぶつかりそう。
その場合もexport PAGER=lessで解決するものもあるかも。
余談
getpreferredencodingいまいち
解決した状態で再びlocale.getpreferredencoding()を実行してみる。
$ python -c "import locale; print(locale.getpreferredencoding(False))"
cp932
やっぱりgetpreferredencodingによる取得はいまいちあやしい。
cmd /? が英語になる
chcp 65001を設定した状態だとcmd /?の結果などは英語になります。
start cmd /?とすれば日本語が表示されます。
参考:
コマンドプロンプト/英語モード・日本語モードの切り替え方法・chcp - Windowsと暮らす
PAGERの仲間
gitでは環境変数GIT_PAGERも使えるらしい。
履歴
2016/09/27 chcpについて記載
2016/10/09 PAGERについて追記