|
すいません、また質問です。 Windows で ActivePerl を使うと、 \r\n を読み込むと \n を読み込んだと思い込み、 \n を書き出すと \r\n を書き出そうとする習性があります。 これを停止するために binmode STDIN; binmode STDOUT; とするのですが、こうすると while (<>) { ... } で読み込もうとするときに、 C:\> perl スクリプト名 < ファイル だとうまくいくのですが、 C:\> perl スクリプト名 ファイル だとうまくいきません。 つまり、<> は引数でファイル名を渡されると、 STDIN 以外のファイルハンドルからファイルを読んでいるようなのですが、 このファイルハンドル名は分かるでしょうか? ActivePerl を Windows 2000 以降で使うと、 スクリプト名に .pl という拡張子を付けると C:\> スクリプト名 でいきなり実行できて便利なのですが、 このスクリプトの中で <> を使うと、 C:\> スクリプト名 ファイル名 だとうまくいくのですが、 C:\> スクリプト名 < ファイル名 だと '<' を第1の引数と思い込んでうまくありません。 動かそうとしてるのはしょうもないファイルダンプツールです。 # fdump.pl #$file = shift; #open IN, $file; #binmode IN; binmode STDIN; binmode STDOUT; #$/ = "\r\n"; while (<>) { # 1行ずつ読み込み $line1 = $line2 = $line3 = ""; # 作業域を初期化 @char = split //; # 1文字ずつ分解 foreach $char (@char) { # 1文字ずつ処理 $line1 .= $char; # 文字をそのまま $line1 にくっつける $hex = unpack "H2", $char; # $charを16進数値に変換して$hexに格納 ($hex1, $hex2) = split //, $hex; # $hexを1文字ずつ分解して$hex1、$hex2に格納 $line2 .= $hex1; # 16進数の前半を$line2にくっつける $line3 .= $hex2; # 16進数の後半を$line3にくっつける } print $line1; # $line1を出力する(改行はもともとついている) print "$line2\r\n"; # $line2+改行を出力する print "$line3\r\n"; # $line2+改行を出力する } |
|
>>3164 has > straceしてみると、どうもpoll()で受信を検出できていないようです。 ほほう、glibc の問題かカーネルの問題かはわかりませんが、今どきの Linux でそんな問題にぶちあたるとは運がいいですね。 ここは一気に UDP・IP スタックを解析して、Linus にパッチを送付する まで頑張ってください。しかし粘りますねぇ (笑) # NIC を変えたらすんなり直ったりして。 >>3169 ふくし % grep '<>' /usr/src/contrib/perl5/* /usr/src/contrib/perl5/toke.c: /* turn <> into <ARGV> */ となったので、それを手がかりに調べてみると、perl(1) に 以下のように書いてありました。 次のループは、 while (<>) { ... # 各行に対するコード } 以下の疑似コードと同等になります。 unshift(@ARGV, '-') if $#ARGV < $[; while ($ARGV = shift) { open(ARGV, $ARGV); while (<ARGV>) { ... # 各行に対するコード } } 本当に binmode ARGV でうまくいくのかどうかは試していません。 他の調べ方としては print %main::; でシンボルテーブルを表示し、 片っ端から試してみる、とかですかね。 |