in reply to Testing the current directory with Cwd and File::Spec

If you want to save the current directory so that you may return to it later, the best way to do it is to open "." (current directory) and save the handle. Then you fchdir() to this handle in order to restore it.

There are several problems with obtaining a text representation of the current directory instead. It may be longer than the system's maximum pathname length, it may change without you noticing (someone else renames a directory that is one of the parents of the current one), and it may even in some cases not be possible to determine what it is (missing permissions?). It is also expensive because you have to walk the chain of parent directories back to the root.

But: How do you fchdir() in Perl?

-Celada

  • Comment on Re: Testing the current directory with Cwd and File::Spec

Replies are listed 'Best First'.
Re^2: Testing the current directory with Cwd and File::Spec
by radiantmatrix (Parson) on Dec 06, 2005 at 00:04 UTC

    I disagree. The easiest way to save the current directory and return to it later is File::chdir, which lets you change directories through a localized variable. Example:

    use File::chdir; print $CWD; # now cd and show me a directory listing { local(@CWD,$CWD); push @CWD,'subdir'; print $CWD; print join("\n", glob '*'); } # now we're back where we started. We'll do a listing to show. print $CWD; print join("\n", glob '*');

    The imported variable $CWD always holds the full path, so you can also just store it to a variable and restore the value later, even mixing things with chdir.

    use File::chdir; my $wd = $CWD; chdir('subdir'); # do some work. $CWD = $wd; # return to saved dir.

    Now, that may not be the best way, but I'd vote for it as easiest. :-)

    <-radiant.matrix->
    A collection of thoughts and links from the minds of geeks
    The Code that can be seen is not the true Code
    "In any sufficiently large group of people, most are idiots" - Kaa's Law
      Now, that may not be the best way, but I'd vote for it as easiest. :-)

      Two comments.

      First, File::chdir uses Cwd and File::Spec internally, which means it's potentially just as subject to the issues raised in the meditation. The Anonymous Monk was suggesting opening and saving the filehandle, not the directory name. That's quite a bit different and would be more robust to name issues. However, the meditation was about comparing the current directory to a desired one -- which in a test suite is specified by name, not filehandle, so that doesn't really help either.

      Second, my hope is that people may find File::pushd to be even easier -- at least for the directory reverting part. Here's something like your first example with File::pushd -- no localization needed:

      use Cwd; use File::pushd; print cwd; { my $dir = pushd('subdir'); print join("\n", glob '*'); } # back where we started print cwd; print join("\n", glob '*');

      And a File::pushd version like your second example -- with no needing to manually change back to a saved directory:

      use File::pushd; { my $wd = pushd(); chdir('subdir'); # do some work. } # automatically back in original dir

      Where it really shines is with temporary directories that need to clean themselves up:

      use File::pushd; { my $wd = tempd(); # do work in the temporary directory } # back in the original directory and the temporary directory is delete +d

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

        xdg,

        To your first comment, I agree that my reply about saving the filehandle instead of the name doesn't address the meditation you were actually pondering. It's more of a comment on my ideal of a cwd save and restore should work in general.

        To your second comment, I agree that the way it works within the framework of existing lexical scoping rules makes it nice and convenient.

        For tempd, it's too bad we can actually create an anonymous directory for this purpose (i.e. create it, change into it, and delete it while still being inside it). (Or even if there are some operating systems permit this, it's certainly not portable).