Posted at

MSYS2のRubyではファイル名をUTF-8で指定しないとならない模様

More than 3 years have passed since last update.

先日、メインマシンで使うコマンドラインツールを極力MSYS2でインストールするようにしたのだが、その結果、日本語を含むファイル名を扱う一部のRubyスクリプトが動かなくなった。

結論から言うと、MSYS2のRubyでファイル名を指定する場合は、スクリプトのエンコーディングに関わらずUTF-8のものを指定しないと、ファイル名を正常に認識できない模様。


例を以下に挙げる。


filename.rb

#!/usr/bin/env ruby

# -*- coding: Windows-31J -*-
puts File.readlines('てすと.txt').size

「てすと.txt」というファイルの行数を出力するだけのスクリプトである。ここでスクリプト2行目にある通り、スクリプトの文字コードはShift_JISで保存しているものとする(なぜWindows-31Jと書くのかについては、例えばこの記事を参照)。

このスクリプトを動かすと、まずRubyの2.3.0p0 x64-mingw32版(RubyInstaller for Windowsで公開されているもの)では

>cat てすと.txt

foo
bar
buz

>ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x64-mingw32]

>ruby filename.rb
3

と意図した通り動いてくれるのだが、Rubyの2.3.0p0 x86_64-msys版(MSYS2のpacmanでインストールできるもの)では

>ruby -v

ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-msys]

>ruby filename.rb
filename.rb:3:in `readlines': No such file or directory @ rb_sysopen - ▒Ă▒▒▒.txt (Errno::ENOENT)

と、シフトJISで書かれたファイル名を正しく認識してくれないのである。

なお、スクリプトを以下のように修正したらx64-mingw32版、x86_64-msys版ともに問題なく動いた。なのでおそらく、MSYS2のファイル処理APIの仕様の違いなのだろうなあ。


filename.rb

#!/usr/bin/env ruby

# -*- coding: Windows-31J -*-
puts File.readlines('てすと.txt'.encode('utf-8')).size
# ファイル名についてはUTF-8にしたものを使う