f

アーカイブ

2015-10-31

CygwinとMSYS2でのWindowsコマンドの文字化け対策

ターミナルの文字エンコーディングをUTF-8に設定したCygwinやMSYS2で,ipconfigなどのWindows標準コマンドを使いたいときがある。しかし,それをすると標準出力や標準エラー出力が文字化けする。この回避策をまとめる。

Introduction

不自由なWindows上でUnixコマンドを使用するツールとしてCygwinやMSYS2が存在する。これらでは,~/.minttyrcに以下を記述すればターミナルから扱える文字エンコーディングをUTF-8に設定できる。

Charset=utf-8

CygwinやMSYS2ではWindowsのコマンドも実行できる。しかし,Windowsのコマンドは標準出力と標準エラー出力の文字エンコーディングがCP932となっている。そのため,CygwinとMSYS2でターミナルの文字エンコーディングをUTF-8にしていると,Windowsのコマンドの実行結果から日本語が文字化けしてしまう。これを回避するためには2通りの方法がある。

  1. ~/.minttyrcの文字エンコーディング設定をCP932にする。
  2. Windows標準コマンドの出力文字エンコーディングを変換する。

1.の方法だと,Windows環境だけのためにその他の設定をすべてCP932に変える必要があるためよくない。2.の方法だと,Windows標準コマンドだけに対して対応すればよいのでこちらがよい。以下では2.の実現方法を説明する。

Windowsコマンドの出力の変換

Windowsコマンドの標準出力と標準エラー出力の文字エンコーディングがCP932であることがわかっているので,iconvnkfコマンドを使って変換する。例えば,以下のように最後にパイプでこれらのコマンドにつなげることで文字エンコーディングを変換して出力できる。

ipconfig 2>&1 | iconv -f cp932 -t utf-8
ipconfig 2>&1 | nkf -w

nkfは標準でインストールされていないことが多いが,iconvはPOSIXで定義されており,多くの場合標準でインストールされている。したがって,iconvを使ったほうがよい,

Windowsコマンド実行の度に上記のコマンドを書くのは煩雑である。そのため,使うことが考えられるWindowsコマンドにaliasを設定する。以下のサイトを参考にして関数を定義すると引数がある場合でも対応できる。

参考:職業としてのプログラミング gnupackでCygwin導入した時に最初にすること

また,LinuxのWine上でもWindows標準コマンドを使うことがありえる。Wine上では文字エンコーディングは既定でUTF-8になっているようなのでaliasを設定するのはWindowsだけにする。これを考慮すると以下のようなaliasの設定となる。

### Windows character encoding convert
if [ "$OS" = "Windows_NT" ]; then
  wincmd(){
    CMD=$1
    shift
    $CMD $* 2>&1 | iconv -f cp932 -t utf-8
  }

  alias ipconfig='wincmd ipconfig'
  alias netstat='wincmd netstat'
  alias netsh='wincmd netsh'
  alias taskkill='wincmd taskkill'
  alias cs='wincmd cscript.exe -NoLogo'
  alias ws='wincmd wscript.exe -NoLogo'
fi

上記内容は~/.bashrcなどに書いておく。これでWindowsコマンドを実行時に日本語が文字化けせずに表示される。

0 件のコメント:

コメントを投稿