それマグで!

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

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

ruby のnucursesでWatchコマンドらしいモノを作る

cygwin で watch コマンドが日本語を画面に出さないので困った.rubyで同じようなモノを作ってみる。やることは次の通り。--定期的に,画面をクリアして,プロセスを実行する

ruby でWatchコマンドらしきモノを作る

  1. 引数はコマンドを受け取る
  2. コマンドは1秒おきに実行する
  3. 実行前に画面を消す
  4. 実行した結果は出力する

差分表示とか時間指定は、基本的な事ができたらやってみる

ruby で nucursesを扱うには

ruby のcusesが日本語を扱わない。結局Watchコマンドと同じ事だと分かった.
日本語(UTF-8)が通るncurses-ruby環境の構築 - nyaxtのPC作業ログ

gem にnucurseswがある

日本語対応のnucurseswを探してみたところ。

gem で curses を調べたら複数見つかった ちなみにcusesは標準バンドルっぽい

takuya@letsnote:~/Desktop$ gem search curses -r

*** REMOTE GEMS ***

cursesx (003)
ffi-ncurses (0.3.3)
ncurses (0.9.1)
ncursesw (1.2.4.3)
snowleopard-ncurses (1.2.4)
takuya@letsnote:~/Desktop$ gem install  ncursesw
Fetching: ncursesw-1.2.4.3.gem (100%)

入れてみて使って見た

Ncuses はRubyバインディングとして作られている
Ncursesを知らないユーザーがちょっとしたことやるには向いてない.
「nucursesは知っとけ」とマニュアルにも書いてある


基本的には ncursesと同じ使い方

>#!/usr/bin/env ruby 
>require 'rubygems'
>require 'ncursesw'
>
>Ncurses.initscr
>Ncurses.initscr(); 
>Ncurses.printw("Hello World !!!");  
>Ncurses.refresh();
>Ncurses.getch();
>Ncurses.endwin();
>p "END"

これはnucursesのマニュアル(以下)をRubyで書いたモノ

もちろん実行スクリプト実行で.irbでやるとダメです.メソッド一覧を>ちょっと覗こうとして、irbから使ってて画面が・・ってなった

>#include <ncurses.h>
>
>int main()
>{	
>	initscr();			/* Start curses mode 		  */
>	printw("Hello World !!!");	/* Print Hello World		  */
>	refresh();			/* Print it on to the real screen */
>	getch();			/* Wait for user input */
>	endwin();			/* End curses mode		  */
>
>	return 0;
>}


よく似てる。ほぼ同じに使えると分かる.特徴はPREFIXが名前空間として付いている

モジュール名を省きたいときは

>include Ncurses::Namespace

を書く。先ほどのコードは以下の様にする.

>#!/usr/bin/env ruby 
>require 'rubygems'
>require 'ncursesw'
>include Ncurses::Namespace
>initscr(); 
>printw("Hello World !!!");  
>refresh();
>getch();
>endwin();
>p "END"

簡単だね

もちろん日本語も

これが最初の目的

>#!/usr/bin/env ruby 
>require 'rubygems'
>require 'ncursesw'
>include Ncurses::Namespace
>initscr(); 
>printw("こんにちは こんにちは!!!");  
>refresh();
>getch();
>endwin();
>p "END"

動きました

では本題.Watch見たく定期的にコマンドを実行して出力を表示


というわけで、Watchコマンドのとてもシンプル版を作ってみた

#!/usr/bin/env ruby 
require 'rubygems'
require 'ncursesw'
include Ncurses::Namespace

puts " set argv[0] for `command` " if ARGV.size < 1 
exit if ARGV.size < 1 
time_to_sleep = 1

cmd = ARGV[0]
begin
initscr();
  loop{
    clear();
    printw(`#{cmd}`);
    refresh();
    sleep time_to_sleep 
  }
rescue  Interrupt => e
ensure 
  endwin();
end

使い方

ruby watch.rb "ls -alt "