Bad file descriptor

K

klaus_gb

I have the following Perl script 'test.pl':

use strict;
use warnings;
while (<>) { print $_; }
print "Message = '$!'\n";

when i run this script with a redirected input-file, it prints the
following:

C:\>test.pl <data.txt
Message = 'Bad file descriptor'

Does anybody have an idea why ?

if I run the script without any redirection, everything works as
expected, i.e. it reads from STDIN and echos on STDOUT, for example:

C:\>test.pl
ABC
ABC
DEF
DEF
^Z
Message = ''


I am using...

C:\>perl -v
This is perl, v5.6.1 built for MSWin32-x86-multi-thread
(with 1 registered patch, see perl -V for more detail)
Copyright 1987-2001, Larry Wall
Binary build 635 provided by ActiveState Corp.
http://www.ActiveState.com
Built 15:34:21 Feb 4 2003

....under Windows XP:
C:\>ver
Microsoft Windows XP [Version 5.1.2600]
 
B

Ben Morrow

I have the following Perl script 'test.pl':

use strict;
use warnings;
while (<>) { print $_; }
print "Message = '$!'\n";

when i run this script with a redirected input-file, it prints the
following:

C:\>test.pl <data.txt
Message = 'Bad file descriptor'

Does anybody have an idea why ?

The info in $! is only valid just after a system call has failed. In
this case, there is no failure, so the value of $! is undefined: that
is, it may contain anything, with there being no particular reason for
it to contain one thing rather than another. In particular, it may
well *not* contain the empty string.

Ben
 
G

gnari

klaus_gb said:
I have the following Perl script 'test.pl':

use strict;
use warnings;
while (<>) { print $_; }
print "Message = '$!'\n";

when i run this script with a redirected input-file, it prints the
following:

C:\>test.pl <data.txt
Message = 'Bad file descriptor'

Does anybody have an idea why ?

something wrong with data.txt?
something wrong with your operating system?

gnari
 
K

klaus_gb

gnari said:
something wrong with data.txt?

This is the hex-dump of data.txt:
ABC.DEF. 41 42 43 0A 44 45 46 0A
something wrong with your operating system?

I don't think so: I have a pre-installed version of Windows-XP which
came with the computer that I bought and I did not make any changes to
the operating system. But on the other hand, test.pl shows an
additional warning when called with a pipe:
C:\>type abc.txt | test.pl
The process tried to write to a nonexistent pipe.
Message = 'Bad file descriptor'

I have also written another version of the script, perl1.pl:

use strict;
use warnings;
open(FN, "<data.txt") or die "Error $!\n";
while (<FN>) { print $_; }
print "Message = '$!'\n";
close FN;

Astonishingly, when I run the test1.pl script, everything works fine:
C:\>test1.pl
ABC
DEF
Message = ''
 
M

Michele Dondi

I have the following Perl script 'test.pl':

use strict;
use warnings;
while (<>) { print $_; }

BTW:

while (<>) { print }

print while said:
when i run this script with a redirected input-file, it prints the
following:

C:\>test.pl <data.txt
Message = 'Bad file descriptor'

Does anybody have an idea why ?

No.

But is there any good reason for not running it as
'C:\>test.pl data.txt'?
if I run the script without any redirection, everything works as
expected, i.e. it reads from STDIN and echos on STDOUT, for example:

Just a wild guess: may it be that you're inadvertently using the -i
switch? Note: to be fair I don't know (and don't have time to check,
sorry!) if it can cause the observed behaviour, but it would seem
reasonable...

Another wild guess, since I am only familiar with command.com and not
cmd.exe: isn't it that for some strange reason, instead of
redirecting, the shell is passing to the script an argument of
'<data.txt'. This is currently what happens with batch files IIRC
(hence some preoblems with pl2bat). However, as you can see by the
simple test below, it should work though. (wouldn't have expected!)

As I said, I just don't have much time left, just pasting here the
results of a few quick experiments. See if by any chance they can
help:

perl -lpe "print $ARGV if $.==1; END{print $!}" test.txt
test.txt
aaa
bbb


perl -lpe "print $ARGV if $.==1; END{print $!}" <test.txt
-
aaa
bbb


perl -lpe "print $ARGV if $.==1; END{print $!}" "<test.txt"
<test.txt
aaa
bbb


perl -lpi.bak -e "print $ARGV if $.==1; END{print $!}" <test.txt
-
aaa
bbb


perl -lpi.bak -e "print $ARGV if $.==1; END{print $!}" "<test.txt"
Can't open <test.txt: No such file or directory.
No such file or directory


Michele
 
K

klaus_gb

Michele Dondi said:
BTW:

while (<>) { print }



No.

But is there any good reason for not running it as
'C:\>test.pl data.txt'?


Just a wild guess: may it be that you're inadvertently using the -i
switch? Note: to be fair I don't know (and don't have time to check,
sorry!) if it can cause the observed behaviour, but it would seem
reasonable...

Another wild guess, since I am only familiar with command.com and not
cmd.exe: isn't it that for some strange reason, instead of
redirecting, the shell is passing to the script an argument of
'<data.txt'. This is currently what happens with batch files IIRC
(hence some preoblems with pl2bat).

Thanks, that's exactly it!

I have consulted the excellent perl documentation, and I could find
the following extract in 'pl2bat.bat' (which is located in my
C:\perl\bin\ directory):

*** C:> ftype Perl=perl.exe "%1" %*
*** C:> assoc .pl=Perl
*** C:> set PathExt=%PathExt%;.PL
*** then
*** C:> script [args]
***
*** [...]
***
*** One major disadvantage [...] is that you can't
*** use them in pipelines nor with file redirection.
*** [...]
***
*** C:> script.pl <infile
*** C:> script.pl >outfile
*** C:> echo y | script.pl
*** C:> script.pl | more
***
*** This is due to a Win32 bug which Perl has no control
*** over. This bug is the major motivation for B<pl2bat>
*** (which was originally written for DOS) being used on
*** Win32 systems.
However, as you can see by the
simple test below, it should work though. (wouldn't have expected!)

Looking at the above extract from 'pl2bat.bat', it seems to me that
the problem only occurs if you register *.pl files with the system
('ftype', 'assoc' and 'pathext') and call your perl-script via the
*.pl file. I guess that when a simple test is performed where perl.exe
is directly called from the command-line, the Win32 bug doesn't have
any effect.
As I said, I just don't have much time left, just pasting here the
results of a few quick experiments. See if by any chance they can
help:

perl -lpe "print $ARGV if $.==1; END{print $!}" test.txt
test.txt
aaa
bbb


perl -lpe "print $ARGV if $.==1; END{print $!}" <test.txt
-
aaa
bbb


perl -lpe "print $ARGV if $.==1; END{print $!}" "<test.txt"
<test.txt
aaa
bbb


perl -lpi.bak -e "print $ARGV if $.==1; END{print $!}" <test.txt
-
aaa
bbb


perl -lpi.bak -e "print $ARGV if $.==1; END{print $!}" "<test.txt"
Can't open <test.txt: No such file or directory.
No such file or directory

I have performed these simple tests on my system, and I can confirm
exactly identical results.
 

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

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,820
Latest member
GilbertoA5

Latest Threads

Top