can't redirect output to a file?!

D

Damien Mattei

i wrote a simple program that read data from STDIN but redirected in a
pipe from a file parse it and wrote output to STDOUT,here is the code:

#!/usr/bin/perl -w

# read the of ethernet vendor codes on STDIN
# and convert it in a 2 columns file
# with Ethernet code and constructor
# separator of output file is tab


use strict; # it's always better to be strict when coding ;-)


# split1line (read split first line)
# read this: 00-00-00 (hex) CORPORATION NAME
# return that: 000000 CORPORATION NAME

sub split1line() {


my @betwtab = split /\t/ , <STDIN>;

my @betwspc = split / / , $betwtab[0];

my @hexaddr = split /-/ , $betwspc[0];

my $vendor = $betwtab[2];

my $ethercode = $hexaddr[0] . $hexaddr[1] . $hexaddr[2] ;

return $ethercode . "\t" . $vendor ;

}





# skip the 6 first lines that do not contain any ethernet code

<STDIN>;
<STDIN>;
<STDIN>;
<STDIN>;
<STDIN>;
<STDIN>;

while (1) {

my $pair = split1line();

print $pair;


my $oneline;

# stop after the next empty line
while (($oneline = <STDIN>) && ($oneline !~ /^\n$/)) {

}

exit(0) if not defined $oneline;



}


it works like that:

cat ../var/oui.txt | ./preformat.pl

but when i try this:

cat ../var/oui.txt | ./preformat.pl > ../var/ieee_ethercodes.dat
Value of <HANDLE> construct can be "0"; test with defined() at
../preformat.pl line 56.


line 56 is this one : while (($oneline = <STDIN>) && ($oneline !~
/^\n$/)) {

the file oui.txt could be downloaded here:

http://standards.ieee.org/regauth/oui/oui.txt

i can, of course, modify the program to write directly the result in a
given file but i want to learn more about this strange error.

any help would be appreciated.
 
R

Ryan Shondell

Damien Mattei said:
i wrote a simple program that read data from STDIN but redirected in
a pipe from a file parse it and wrote output to STDOUT,here is the
code: (snip)

cat ../var/oui.txt | ./preformat.pl > ../var/ieee_ethercodes.dat
Value of <HANDLE> construct can be "0"; test with defined() at
./preformat.pl line 56.

This warning means that <STDIN> could return the value "0". This would
make your conditional statement for your while loop false, and
terminate the loop unintentionally. The warning is suggesting you use
'defined', so that if the handle returns 0, the loop won't exit.

while( defined($oneline = <STDIN>) && ($oneline !~/^\n$/)) {
^^^^^^^

Also, you may find it helpful to check 'perldoc perldiag' if you see
an error or warning you don't recognize. Or, put 'use diagnostics' in
your program, and it will display the information from perldiag about
any warnings or errors it finds.
 
G

Greg Bacon

: [...]
:
: it works like that:
:
: cat ../var/oui.txt | ./preformat.pl
:
: but when i try this:
:
: cat ../var/oui.txt | ./preformat.pl > ../var/ieee_ethercodes.dat
: Value of <HANDLE> construct can be "0"; test with defined() at
: ./preformat.pl line 56.
:
: line 56 is this one : while (($oneline = <STDIN>) && ($oneline !~
: /^\n$/)) {

The warning is there in both cases, but redirecting stdout makes it
more obvious. The fix is to add a defined test:

while (defined($oneline = <STDIN>) && ($oneline !~ /^\n$/)) {

Below is a suggestion for further simplifying your code:

#! /usr/local/bin/perl

use strict;
use warnings;

# split1line (read split first line)
# read this: 00-00-00 (hex) CORPORATION NAME
# return that: 000000 CORPORATION NAME

sub next_pair {
local $/ = "";

my $h = qr/[A-Fa-f0-9][A-Fa-f0-9]/;

RECORD: {
local $_ = <>;
return unless defined $_;

redo if /^\s*OUI\b/;

unless (/^($h)-($h)-($h)\s+\(hex\)\s+(.+?)\n/s) {
warn "$0: record $.: no match";
return;
}

return "$1$2$3", $4;
}
}

while (my($ethercode, $vendor) = next_pair) {
print $ethercode, "\t", $vendor, "\n";
}

Hope this helps,
Greg
 
J

John W. Krahn

Damien said:
[snip]

it works like that:

cat ../var/oui.txt | ./preformat.pl

but when i try this:

cat ../var/oui.txt | ./preformat.pl > ../var/ieee_ethercodes.dat
Value of <HANDLE> construct can be "0"; test with defined() at
./preformat.pl line 56.

line 56 is this one : while (($oneline = <STDIN>) && ($oneline !~
/^\n$/)) {

In older versions of Perl you had to explicitly test for definedness if
you were assigning from <> in scalar context.

while ( defined( $oneline = <STDIN> ) && ( $oneline !~ /^\n$/ ) ) {

Or:

while ( defined( $oneline = <STDIN> ) ) {
next unless $oneline =~ /./;




John
 
B

Brian Harnish

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

i wrote a simple program that read data from STDIN but redirected in a
pipe from a file parse it and wrote output to STDOUT,here is the code: [snip script...]
it works like that:

cat ../var/oui.txt | ./preformat.pl

but when i try this:

cat ../var/oui.txt | ./preformat.pl > ../var/ieee_ethercodes.dat
Value of <HANDLE> construct can be "0"; test with defined() at
./preformat.pl line 56.


line 56 is this one : while (($oneline = <STDIN>) && ($oneline !~
/^\n$/)) {

Yes, its a good warning. What happens to your while loop if a line of
stdin matches /^0$/? Answer: the while expression stops. You can get a
better explanation if you also "use diagnostics;". $oneline = <STDIN> will
assign zero to $oneline. The value of $oneline will be returned to the
while, which will interpret that as boolean, and loop stops.

Also, your code is huge. Try this:
#!/usr/bin/perl -w
use strict;

$_ = <> for(1..6); #skip first 6 lines;

while(defined($_ = <>)) {
chomp;

# Seperate fields by whitespace (except the name)
my @fields = split /\s+/, $_, 3;
my @hex = split /-/, $fields[0];
print join('',@hex), "\t", $fields[2], $/;

# Skip until next blank line
$_ = <> until(!defined($_) || /^$/);
}
__END__

- Brian

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)

iD8DBQE/VOFHiK/rA3tCpFYRAmjEAKDg1mKZ3oe5R0RAl+Pkrm7/lUk2ZwCfUQxJ
o2fyWo2qotinaJ2swI35CP0=
=38r8
-----END PGP SIGNATURE-----
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top