それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Cygwin(msys)のUTF-8環境便利にするコマンドラッパー

CygwinでMinttyを使い始めて半年がたちました.Minttyだと全てがUTF-8環境になります.UTF-8環境だとLinuxサーバーのSSHと相性がよくSambaを経由しなくても文字コードに悩むことなく快適に文字を編集できました.

mintty + utf8がマジおすすめ

mintty はとても使いやすいCUIですWindowsで一番便利なのではないでしょうか.poderosa/putty/コマンドプロンプト・・・etc イロイロ試しましたが,Minttyになってからとても快適になりました.




ping文字化けが困りました.

Windowsping.exeは出力を cp932で出します。mintty+BashはUTF8で統一。化けます.

解決策は nkf などにかけることですが.もっと良い解決方法があります.コマンドラッパーを作る事です

文字化けしないPingを作る→ping.exeのラッパーを作る

ping コマンドをWrapperで文字コード対応してしまうのが楽ちんでよりシームレスです

/usr/local/bin/ping
#!/usr/bin/env ruby
KCODE='u'
require "kconv"
cmd = File.basename(__FILE__) +".exe " + $*.join('  ')
IO.foreach("| #{cmd} 2>&1 "){|line|puts line.kconv(Kconv::UTF8,Kconv::SJIS)}

このようなラッパーを書きました。万事解決です.

ipconfig も化けるよう

先ほどの ping をコピーすれば解決です

cp /usr/local/bin/ping /usr/local/bin/ipconfig

ifconfing が良いんだけど

Windowsのコマンドとコマンド名が変わるときは、File.basename(__FILE__)出来ないので、直書きします.

#!/usr/bin/env ruby
KCODE='u'
require "kconv"
cmd = "ipconfig.exe " + $*.join('  ')
IO.foreach("| #{cmd} 2>&1 "){|line|puts line.kconv(Kconv::UTF8,Kconv::SJIS)}

nslookupもしたい

ドメイン名を調べたいです.Cygwinにはコマンドがないので,ラッパーで対応します

cp /usr/local/bin/ping /usr/local/bin/nslookup


arp もみたい

同じです.ラッパーで対応できます

cp /usr/local/bin/ping /usr/local/bin/arp

getmacもしたい

同じです.ラッパーで対応できます

cp /usr/local/bin/ping /usr/local/bin/getmac

cscript.exeもつかいたい

cscript.exeのように引数にファイル名を取るモノはやっかいです.CygwinUNIXパス名を解釈できないですからね。引数のパス名をWindowsパス名に変えて起動します.

/usr/local/bin/cscript
#!/usr/bin/env bash
function cygpath_to_winpath(){
  args=()
  for i in $@ ; do
    if [ -s $i ]; then
      args=(${args[@]} `cygpath -w $i`)
    else
      args=(${args[@]} $i)
    fi
  done
  echo ${args[@]}
  return 0
}
cscript.exe  `cygpath_to_winpath $@` | nkf -w

pythonruby (mswin) のようにshebang で使われるコマンドの場合

ruby(win32) のgem コマンドのように、shebang で使われるコマンドの場合、配慮が必要で。

/usr/local/bin/ruby を、C:/Ruby/bin/ruby の代用として使う。shebangで使われるので、shebang で渡されるCygwinのPathを変換して渡す必要がある。

/usr/local/bin/ruby
#!/bin/env bash
args=("$@")
argn=$#


## 引数でファイルパスになるものは全部Windowsパスに変換する
for i in $( seq $argn )
do
	#echo $i;
	v=${args[$i-1]}
	#echo $v
	if [ -e $v ]; then
		#echo $v exists
		v=`cygpath -ma $v`
		args[$i-1]=$v
	fi
	#echo ${args[$i-1]}
done

/cygdrive/c/Ruby/bin/ruby ${args[@]}

などととする

cygwinUTF-8/SJISで切替えて使うんです

utf-8CygwinコマンドプロンプトSJISも両方使うとき、環境変数をみて出力文字コードに変換するラッパーにしてみたり

/usr/local/bin/route
  1 #!/usr/bin/env ruby
  2 require "kconv"
  3 require "stringio"
  4 $stderr = StringIO.new
  5
  6 $*.unshift "print" if $*.size < 1
  7 out_kcode = Kconv::UTF8
  8 out_kcode = Kconv::UTF8 if "utf-8"== ENV["LANG"].split(".").last.downcase
  9 out_kcode = Kconv::SJIS if "sjis" == ENV["LANG"].split(".").last.downcase
 10 IO.foreach("|#{File.basename($0)}.exe #{$*.join(' ')}"){|line|puts line.kconv(out_kcode,Kconv::SJIS)}
 11

win版PHP使う(空白を含むパス)

cygwin版のphp は微妙なので windows版のPHPを使う

  1 #!/usr/bin/env ruby
  2 require "kconv"
  3 require "stringio"
  4 $stderr = StringIO.new
  5 out_kcode = Kconv::UTF8
  6 out_kcode = Kconv::UTF8 if "utf-8"== ENV["LANG"].split(".").last.downcase
  7 out_kcode = Kconv::SJIS if "sjis" == ENV["LANG"].split(".").last.downcase
  8 $*.map!{|e|  unless  e =~ /^\-/ then  %!'#{e}'! else e end }
  9 IO.foreach("|/home/Public/apps/php/php.exe #{$*.join(' ')}") {|line|puts line.kconv(out_kcode,Kconv::SJIS)}

php の場合 document and settings とかちょっとややこしい空白を含むファイル名にアクセスルのでクォートを挟む処理を加えた



cygwin + utf8 はラッパー使うのが便利

ruby 1.9が無いよう・・・とか php が無いよう・・・とか文字化けが ping がとか考える前にラッパーを作ってそれっぽくだましだまし使うのもいいかな