-d file test operator not working (windows)

H

Hike Mike

I am trying to read the contents of a directory path argument and make
a list of only the directories found in the path. I am only getting
'.' and '..' when using the -d test file operator on windows xp when
the path contains other directories besides.

I have a directory with contents:
I have cygwin installed on windows xp so don't be confused by unix
commands like 'ls';

U:\perl\foo>ls -al
total 1
drwxr-xr-x 1 Michael mkpasswd 0 Jul 21 09:39 .
drwxr-xr-x 1 Michael mkpasswd 0 Jul 21 09:42 ..
drwxr-xr-x 1 Michael mkpasswd 0 Jul 21 09:40 dir1
drwxr-xr-x 1 Michael mkpasswd 0 Jul 21 09:40 dir2
-rw-r--r-- 1 Michael mkpasswd 10 Jul 21 09:39 file1

I want to list only dir1 and dir2

when run my script in the parent directory from

U:\perl>.\synchDir.pl foo

the output is:
found directory: .
found directory: ..

but i think is should be:
found directory: .
found directory: ..
found directory: dir1
found directory: dir2

The code I wrote is:

__BEGIN__

#!/usr/bin/perl

use strict;
use warnings;


my $fromArg = $ARGV[0];
unless ($fromArg) {
die "must supply a source directory to synchronize from as first
argument\n";
}

opendir (FROMDIR, "$fromArg") or die "ummmm: $fromArg: $!\n";
while (my $file = readdir(FROMDIR)) {
next unless -d $file;
print "found directory: $file\n";
}

__END__

and the following change (to remove '.' and '.." from the list of
directories) yeilds no output:

__BEGIN__

while (my $file = grep !/^\./, readdir FROMDIR) {
next unless -d $file;
print "found directory: $file\n";
}

__END__
 
G

Gunnar Hjalmarsson

Hike said:
opendir (FROMDIR, "$fromArg") or die "ummmm: $fromArg: $!\n";
while (my $file = readdir(FROMDIR)) {
next unless -d $file;
print "found directory: $file\n";
}

readdir() does not return full paths.

perldoc -f readdir

Try:

next unless -d "$fromArg/$file";
 
D

Debo

On Thu, 21 Jul 2005, Hike Mike wrote:
HM> I am trying to read the contents of a directory path argument and make
HM> a list of only the directories found in the path. I am only getting
HM> '.' and '..' when using the -d test file operator on windows xp when
HM> the path contains other directories besides.

I didn't actually have time to try this, but perldoc -f readdir suggests
that you either chdir() to the dir in question or prepend the leading
directories in the path if you want to use a filetest on readdir output. I
notice that you're not doing that (as far as I can tell). Perhaps this is
something you could try?

-Debo
 
P

Paul Lalli

Hike said:
opendir (FROMDIR, "$fromArg") or die "ummmm: $fromArg: $!\n";
while (my $file = readdir(FROMDIR)) {
next unless -d $file;
print "found directory: $file\n";
}

-d is working perfectly. Your code contains a bug.

You should probably read the warning in
perldoc -f readdir

Paul Lalli
 
H

Hike Mike

readdir() does not return full paths.
perldoc -f readdir

big help
Try:
next unless -d "$fromArg/$file";

#!/usr/bin/perl
#Starkie, Michael C.

use strict;
use warnings;


my $fromArg = $ARGV[0];
unless ($fromArg) {
die "must supply a source directory to synchronize from as first
argument\n";
}

opendir (FROMDIR, "$fromArg") or die "ummmm: $fromArg: $!\n";
while (my @file = grep {!/^\./ && -d "$fromArg/$_"} readdir FROMDIR) {
print "found directory: @file\n";
}

works
 
A

A. Sinan Unur

readdir() does not return full paths.
perldoc -f readdir

big help
Try:
next unless -d "$fromArg/$file";

#!/usr/bin/perl
#Starkie, Michael C.

use strict;
use warnings;


my $fromArg = $ARGV[0];
unless ($fromArg) {
die "must supply a source directory to synchronize from as first
argument\n";
}

opendir (FROMDIR, "$fromArg") or die "ummmm: $fromArg: $!\n";

perldoc -q always
while (my @file = grep {!/^\./ && -d "$fromArg/$_"} readdir FROMDIR) {
print "found directory: @file\n";
}

works

I don't know what you mean by works, as running this script on my system
with

D:\Home\asu1\UseNet\clpmisc> sss \

produced no output at all.

I don't have the inclination to try to figure out what exactly you did
wrong right now, but your while loop looks very suspicious to me.

In addition, I do think that there is no point in writing code that is
platform specific if it is easy to avoid it.

Also, I don't think you meant to skip every directory whose name starts
with a period, but . and .. only.

#!/usr/bin/perl

use strict;
use warnings;

use File::Spec::Functions 'catfile';

die <<ERR unless @ARGV;
Supply a source directory to synchronize from as first argument

ERR

my $source = shift;

opendir my $source_dir, $source
or die "Cannot open $source directory for reading: $!";

while(my $entry = readdir $source_dir) {
next if $entry eq '.' or $entry eq '..';
my $f = catfile $source, $entry;
next unless -d $f;
print "$f\n";
}

closedir $source_dir
or die "Cannot close $source directory: $!";

__END__


D:\Home\asu1\UseNet\clpmisc> ttt \
\System Volume Information
\Recycled
\Home
\Dload
\organize_this
\Repos
\Work
\Books
\WWW

Sinan
 
G

Gunnar Hjalmarsson

A. Sinan Unur said:
Hike Mike said:
my $fromArg = $ARGV[0];
unless ($fromArg) {
die "must supply a source directory to synchronize from as first
argument\n";
}

opendir (FROMDIR, "$fromArg") or die "ummmm: $fromArg: $!\n";

perldoc -q always
while (my @file = grep {!/^\./ && -d "$fromArg/$_"} readdir FROMDIR) {
print "found directory: @file\n";
}

works

I don't know what you mean by works, as running this script on my system
with

D:\Home\asu1\UseNet\clpmisc> sss \

produced no output at all.

Well, the use of 'while' is obviously redundant, but besides that (and
the unnecessary quotes), the code is taken from "perldoc -f readdir".
Accordingly, if there is anything else you consider to be wrong, it's
time to post a bug report. ;-)
 
A

A. Sinan Unur

A. Sinan Unur said:
Hike Mike said:
my $fromArg = $ARGV[0];
unless ($fromArg) {
die "must supply a source directory to synchronize from as first
argument\n";
}

opendir (FROMDIR, "$fromArg") or die "ummmm: $fromArg: $!\n";

perldoc -q always
while (my @file = grep {!/^\./ && -d "$fromArg/$_"} readdir FROMDIR)
{
print "found directory: @file\n";
}

works

I don't know what you mean by works, as running this script on my
system with

D:\Home\asu1\UseNet\clpmisc> sss \

produced no output at all.

Well, the use of 'while' is obviously redundant, but besides that (and
the unnecessary quotes), the code is taken from "perldoc -f readdir".
Accordingly, if there is anything else you consider to be wrong, it's
time to post a bug report. ;-)

Well, the issue is the fact that I used \ to refer to the root of the
current drive in Windows. That is a perfectly legitimate thing to do,
but when you use interpolation

"$fromArg/$_"

becomes

\/Recycled
\/Home

for which the -d test fails.

etc. On the other hand, if one used File::Spec::Functions::catfile, then
one would get:

\Recycled
\Home

and the -d test would succeed.

I do cringe whenever I see "$dir/$file" rather than catfile $dir, $file.

So, maybe I should file a bug report. I am not sure if I am going to be
able to get to that though. Good news for everyone here: I am going to
be away for a few weeks, starting early tomorrow morning EST.

Sinan
 
G

Gunnar Hjalmarsson

A. Sinan Unur said:
I do cringe whenever I see "$dir/$file" rather than catfile $dir, $file.
Okay...

Good news for everyone here: I am going to
be away for a few weeks, starting early tomorrow morning EST.

Good news? Not at all!

But you do deserve the rest. :)
 

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,774
Messages
2,569,596
Members
45,128
Latest member
ElwoodPhil
Top