in reply to Is there a -e test for directories, like there is for files?

-e does return true for directories (and any other kinds of file).
-f checks only for plain files.
-d checks only for directories.

But do you really need to check if the dir exists? You could just try to make the directory unconditionally.

# Try to make the directory in case it doesn't exists. mkdir($dir); # or mkpath($dir); opendir($dir) or die("Unable to open dir \"$dir\": $!\n"); ...

You might be interested in (core module) File::Path's mkpath instead of mkdir. It creates intermediary directories as needed.

Replies are listed 'Best First'.
Re^2: Is there a -e test for directories, like there is for files?
by mdunnbass (Monk) on Feb 08, 2007 at 20:41 UTC
    OK, so thanks for the advice, all 3 of you. I tried out your suggestions, and got a temp script up and running. I threw in a bunch of print statements, to see what was happening, and it all looks good. But, something isn't working right. Somehow, the grep statement in the if isn't coming out right. I thought to use
    if (-e $back)
    instead of
    if (grep {$back} @files),
    but I am unsure how to test for files in a different directory..

    #! /usr/bin/perl use strict; use warnings; use File::Path; use File::Copy; use Cwd; print "Your Input: "; chomp(my $filename = <STDIN>); my $dir = getcwd; my $backupdir = 'backup_files'; my $back = $filename . ".bak"; my $backful = $dir . "/" . $backupdir . "/" . $back; print "\$dir is: $dir\n"; print "\$filename is: $filename\n"; print "\$backupdir is: $backupdir\n"; print "\$back is: $back\n"; print "\$backful is: $backful\n"; unless (-e $backupdir) { mkpath($backupdir); } if (-e $backupdir) { if (-d $backupdir) { opendir (DIR, $backupdir) or die $!; my @files = readdir DIR; print "\@files is: \n"; foreach (@files) { print $_, "\n"; } if (grep {$back} @files) { print "Backup copy of $filename exists!\n"; } else { copy ($filename, $backful); print "Backup copy of the file has been created\n"; } } else { print "\$backupdir exists, but it is not a directory\n"; } }

    Any thoughts on where I am going wrong?

    Thanks

      -e $backful

      Update: Specifically, replace

      opendir (DIR, $backupdir) or die $!; my @files = readdir DIR; print "\@files is: \n"; foreach (@files) { print $_, "\n"; } if (grep {$back} @files) { print "Backup copy of $filename exists!\n"; } else { copy($filename, $backful); print "Backup copy of the file has been created\n"; }
      with
      if (-e $backful) { print "Backup copy of $filename exists!\n"; } else { copy($filename, $backful); print "Backup copy of the file has been created\n"; }

      You should check whether the backup is the same, not whether it exists.
      You should check whether the copy succeeded.
      You should fix up your indenting.

        Wait - what's wrong with my indenting? I usually do:
        if (conditions) { do something } while (<>) { etc.. }

        The only thing I can see that's different is where I indent the closing brackets to. I usually put them even with the do something rather than even with the if (conditions). Is that wonky?

        Huh. Oh. I guess I could try to convert my habit.....

        But seriously, thanks for the help. I may have one or two additional things later on having tangentially to do with this, but for now, I'm great. Thanks.

        Matt

      chomp(my $filename = <STDIN>); my $dir = getcwd; my $backupdir = 'backup_files'; my $back = $filename . ".bak"; my $backful = $dir . "/" . $backupdir . "/" . $back;

      May I suggest slightly cleaner alternatives?

      use File::Basename qw( basename ); use File::Spec::Functions qw( catfile ); chomp(my $filenameful = <STDIN>); my $filename = basename($filenameful); my $backupdir = 'backup_files'; my $back = $filename . ".bak"; my $backful = catfile($backupdir, $back);
      use File::Basename qw( basename ); use File::Spec::Functions qw( catfile rel2abs ); chomp(my $filenameful = <STDIN>); $filenameful = rel2abs($filenameful); my $filename = basename($filenameful); my $backupdir = 'backup_files'; my $back = $filename . ".bak"; my $backful = rel2abs(catfile($backupdir, $back));

      They both allow a path to be attached to the input.
      They both use the right directory seperator for the platform being used.
      They both cannonize the path, so foo//bar would become foo/bar.
      The first creates a relative path while the second creates an absolute one.

        Voondibah!

        Thank you!