lostbits
lostbits

Reputation: 1054

Why is opendir argument invalid?

This is perl 5, version 30, subversion 1 (v5.30.1) built for MSWin32-x64-multi-thread
Win10
cygwin

I can't figure out how to use opendir. Here is my example code:

sub test($) {
   my $dir     = shift;
   opendir (DIR, $dir) || die "Couldn't open dir $dir $!";
}
sub main() {
   my $dir = `pwd`;
   test($dir);
}

Error message

Couldn't open dir /home/skidmarks/Projects/Perl
 Invalid argument at ./test.py line .

pwd returns a unix formatted directory path ('/'). I have tried it with a windows formatted directory path ('\'). The only thing that works is to use a literal string for the path, e.g., "." or "some_directory_path".

Can't I use a variable in opendir for the path?

Upvotes: 1

Views: 863

Answers (3)

zdim
zdim

Reputation: 66883

The qx (backticks) returns the newline as well, so you need chomp $dir;.

Better yet, why not use Perl's facilities

use Cwd qw(cwd);

my $dir = cwd;

and now you don't have to worry about system commands and how exactly they return.


As the OP uses pwd from cygwin, even once the linefeed is gone the obtained path is unix-style and this conflicts with MSWin32 build of Perl (as reported when opening the file). Using a portable tool (like Cwd above) and a Windows build of Perl should avoid such problems.

Or use a tool to convert paths, like cygpath. See this post

Upvotes: 6

Polar Bear
Polar Bear

Reputation: 6798

Latest version of Cygwin was installed and tested with slightly modified code -- works fine.

NOTE: pwd is Linux/UNIX command which produces an error in MS Windows, but works in Cygwin which emulates Linux/UNIX environment (binary incompatible, requires recompilation of the programs)

#!/usr/bin/perl

use strict;
use warnings;

use feature 'say';

sub test($) {
   my $dir = shift;

   opendir(my $dh, $dir)
        or die "Couldn't open dir $dir $!";

   map{ say } readdir($dh);

   close $dh;
}

sub main() {
   my $dir = `pwd`;
   chomp $dir;

   print "[$dir]\n";

   test($dir);
}

main();

Function main is not required in perl (main() function is C/C++ entrance point) and normally code looks like following

#!/usr/bin/perl

use strict;
use warnings;

use feature 'say';

my $dir = `pwd`;          # pwd is UNIX/Linux command will give an error in MS Windows

chomp $dir;               # trim \n at the end of $dir

say "DIRECTORY: [$dir]";  # Let's check what we got

test($dir);

sub test {
   my $dir = shift;

   opendir(my $dh, $dir)
        or die "Couldn't open dir $dir $!";

   map{ say } readdir($dh);

   close $dh;
}

Upvotes: 1

Polar Bear
Polar Bear

Reputation: 6798

Try following piece of code, it works well with Strawberry perl.

Also try to put full path in double quotes "c:\Program Files\Common Files".

If directory name is not provided then the script will list current directory

Usage: perl script.pl "C:\Users\User_name"

use strict;
use warnings;

use feature 'say';

my $dir_name = shift || '.';

opendir(my $dir, $dir_name)
    or die "Couldn't open $dir_name";

map{ say } readdir($dir);

closedir $dir;

NOTE: Navigate in Cygwin terminal to target directory and issue command pwd. Perl script run in Cygwin perhaps will expect the path in this form.

Upvotes: 1

Related Questions