重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

以下のスクリプトをWindowsで動かしたときにはちゃんと最後まで動くのに対し、Linuxで動かすとループの2週目でとまってしまいます。
こういうことって結構よくあることなんですか??
解決法などご存知の方いたら教えてください
ーーーーーーーーーー
PKTMP="C6C6nCCnnnCCnC4C4"
HEADLEN=34
ST = Struct.new(:tomac,:frommac,:toip,:fromip,:ttl,:prot,:data)
def analyze(data)
 result = Array.new
 i=0
 while data
  head = data.unpack(PKTMP)
  if (head[12] != 0x800) || (head[13] != 0x45)
   result << "error! in No.#{i} packet"
   return result
  end
  tmp = ST.new
  tmp.tomac = macaddr(head,0)
  tmp.frommac= macaddr(head,6)
  tmp.toip = ipaddr(head,-8)
  tmp.fromip=ipaddr(head,-4)
  tmp.ttl = sprintf("%d",head[18])
  tmp.prot = sprintf("%d",head[19])
  data.slice!(0...HEADLEN)
  datalen = head[15] - (head[13] & 0xf)*4
  tmp.data = data.slice!(0...datalen)
  result << tmp
  i+=1
 end # end of (while data )
 return result
end

A 回答 (5件)

#1,#2,#4です。

すいません。さっきの半分無しにしてください。
開発版の1.9.0を使うべきでないと言うところは良いのですが、原因は、Rubyの不具合じゃなくて、1.8系と1.9系の仕様の違いですね。

1.9系では、slice!を初めとする「文字列の一部を数字で位置指定する」機能が変更になってます。
1.8系がバイト単位で、1.9系が文字単位です。指定しないとデフォルトがUS-ASIIだから同じだろうと思っていましたが、何も指定しないでファイルから読むと、OSの標準(Linuxだと環境変数LANG)の文字コードになります。なお、US-ASCIIだと\x80~\xFFのバイトがエラーに。

1.9系のRubyを使うのなら、プログラム先頭で、
Encoding.default_external = "BINARY" if RUBY_VERSION > "1.9"
としてください。
    • good
    • 0
この回答へのお礼

ありがとうございます。
ちゃんとバイナリ単位でデータをやり取りできるように修正したいと思います

お礼日時:2010/02/26 15:03

#1,#2です。


失礼しました。
1.9.0のRubyというのは、テストされてリリースされたものではなく、開発版です。開発途上版というか、よくベータ版ソフトとかありますが、ベータ版ですらなくて、「こういう機能を追加・変更してみました」的に、日々プログラムが書き換えられています。Rubyインタプリタやライブラリの開発者が使うものです。
2008-06-20版がどういう変更を加えられたものかはわかりませんが、お使いの機能の部分の機能変更や処理ロジック変更があった直後であれば、テストが足りてない可能性があります。

実用で使うのであれば、リリース版である、1.8.6 か 1.8.7 か 1.9.1 を使ってください。
特徴は、
1.8.6 → 現在の書籍はほとんどこれに準拠。バージョンを指定せず公開されているソフトもまず間違いなく動く。
1.8.7 → 1.8.7 に 1.9系の一部新機能を追加したもの。1.8.6 と(100%ではないが)上位互換性がある。
1.9.1 → 高速化されて、機能追加や、文字コードその他の機能変更。まだ新しいバージョンなので、公開されているソフトが全部動くわけではない。これに準拠した書籍も少ない。

Linuxのパッケージ管理システムでインストールされるのは、ほとんど(orすべて)のディストリビューションで今のところ1.8.6だと思います。
1.9.0が入っていると言うことは、誰かがソースからコンパイルしてインストールしたものですね。
    • good
    • 0
この回答へのお礼

ありがとうございます
Rubyのバージョンを変えたらちゃんと動くようになりました
自分がちゃんと開発バージョンかどうかをチェックしなかったのが悪かったんですね。

お礼日時:2010/02/26 14:48

Windowsとlinuxで動きが違う、と言われて、まっさきに思い浮ぶのは、改行とエンコーディングですが....



データの読み出しをテキストモードでやってるとかはありませんか?
    • good
    • 0
この回答へのお礼

それも大丈夫です
問題の関数をrequireしているのが↓です。
自分はこのスクリプトに引数を与えて起動したのでちゃんと"rb"で開けているはずだと思います。
あと、このスクリプトを(動かなかったPCじゃない)他のLinuxのPCにさして
同じようにやってみたらそっちはちゃんと動きました。

ちなみに動かなかったほうのRubyのバージョンは
ruby 1.9.0 (2008-06-20 revision 17482) [i486-linux]
なんですが、このバージョンには何か特別な問題でもあるんでしょうか?
------main.rb------------
require "analyze.rb"
input = open(ARGV.shift,"rb")
output = STDOUT
data = input.read
res = analyze(data)
res.each{|packet|
p packet
}

お礼日時:2010/02/26 03:45

>ということはRubyのバグと見ていいんでしょうか??



Rubyにバグはまだあるでしょうけど、こういう簡単なレベルでは出てきません。

おそらくは、データのコピーミスとか、テストミス、確認ミスなどが原因です。

あと、
while data
だと無限ループになるので、
while data != ""
として、dataが空文字列になったら終了した方がよくないですか?
    • good
    • 0
この回答へのお礼

ループの件はおっしゃるとおりです。
ありがとうございます。

WindowsとLinuxの二つの環境で試したというのは、
一つのUSBメモリの中に解析するデータとこのスクリプトを入れて

そのUSBメモリをWindowsにさして中身を実行、
次にLinuxのPCに差し変えて実行、

というようにやったのでデータのコピーミスとかは無いはずだと思います

お礼日時:2010/02/26 02:23

書かれている範囲では、WindowsとLinuxで動作の違う機能は無いので、データが同じなら動作も同じはずです。

    • good
    • 0
この回答へのお礼

ありがとうございます。
やはり違いは無いんですね。
ということはRubyのバグと見ていいんでしょうか??

お礼日時:2010/02/26 01:12

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!